Экспериментальный раздел




Содержание

 

Введение 5

1. Постановка задачи 7

2. Теоретический раздел 9

2.1 Достоинства ООП 10

2.2 Недостатки ООП 11

3. Проектный раздел 17

3.1 Классы 18

3.2 Алгоритм 20

4. Экспериментальный раздел 21

4.1 Описание программы 22

Заключение 24

Список использованных источников 26

Приложение А. Листинг программы 28

 


 

 

Введение

 

Концепция объектно-ориентированного программирования подразумевает, что основой управления процессом реализации программы является передача сообщений объектам. Поэтому объекты должны определяться совместно с сообщениями, на которые они должны реагировать при выполнении программы. В этом состоит главное отличие ООП от процедурного программирования, где отдельно определённые структуры данных передаются в процедуры (функции) в качестве параметров. Таким образом, объектно-ориентированная программа состоит из объектов - отдельных фрагментов кода, обрабатывающего данные, которые взаимодействуют друг с другом через определённые интерфейсы.

Объектно-ориентированный язык программирования должен обладать следующими свойствами:

1. абстракции - формальное о качествах или свойствах предмета путем мысленного удаления некоторых частностей или материальных объектов;

2. инкапсуляции - механизма, связывающего вмести код и данные, которыми он манипулирует, и защищающего их от внешних помех и некорректного использования;

3. наследования - процесса, с помощью которого один объект приобретает свойства другого, т.е. поддерживается иерархической классификации;

4. полиморфизма - свойства, позволяющего использовать один и тот же интерфейс для общего класса действий.

Разработка объектно-ориентированных программ состоит из следующих последовательных работ:

- определение основных объектов, необходимых для решения данной задачи;

- определение закрытых данных (данных состояния) для выбранных объектов;

- определение второстепенных объектов и их закрытых данных;

- определение иерархической системы классов, представляющих выбранные объекты;

- определение ключевых сообщений, которые должны обрабатывать объекты каждого класса;

- разработка последовательности выражений, которые позволяют решить поставленную задачу;

- разработка методов, обрабатывающих каждое сообщение;

- очистка проекта, то есть устранение всех вспомогательных промежуточных материалов, использовавшихся при проектировании;

- кодирование, отладка, компоновка и тестирование.

Объектно-ориентированное программирование позволяет программисту моделировать объекты определённой предметной области путем программирования их содержания и поведения в пределах класса. Конструкция «класс» обеспечивает механизм инкапсуляции для реализации абстрактных типов данных.

Инкапсуляция как бы скрывает и подробности внутренней реализации типов, и внешние операции и функции, допустимые для выполнения над объектами этого типа.

 


 

 

Постановка задачи

 

 

Рассматривается движение автомобилей на прямом однорядном (однополосном) участке автострады без перекрестков, в течение некоторого времени. Автомобили появляются на одном конце дороги и проезжают по ней до другого конца, стараясь по возможности сохранить начальную (заданную при их появлении) скорость.

Когда автомобиль приближается к идущей впереди машине на допустимое расстояние, он начинает притормаживать по определенному закону, пока его скорость не сравняется со скоростью передней машины.

Пусть в таком потоке машин организована искусственная кратковременная задержка одного автомобиля: автомобиль сначала резко замедляется, сбрасывая за некоторое время скорость, а затем после некоторой паузы вновь набирает первоначальную скорость. В результате, если следующий автомобиль не успел притормозить, возникает авария. Может возникнуть и так называемая пробка – область с высокой плотностью автомобилей, включающая чередование притормаживаний и ускорений до прежней скорости. Действительно, если какой-то автомобиль начинает резко замедляться, идущий за ним автомобиль тоже через некоторое время тормозит. После торможения следует замедленное движение автомобиля.

Пробка обычно возникает, если плотность потока автомобилей достаточно велика, и существует некоторое время, медленно двигаясь навстречу потоку автомобилей и постепенно рассеиваясь.

Заметим, что в аварию может попасть не тот автомобиль, что был искусственно задержан, а идущие за ним машины. В случае аварии должно пройти некоторое фиксированное время, прежде чем движение на этом участке вновь станет возможным.

 


 

Теоретический раздел

 


 

Достоинства ООП

От любого метода программирования мы ждем, что он поможет нам в решении наших проблем. Но одной из самых значительных проблем в программировании является сложность. Чем больше и сложнее программа, тем важнее становится разбить ее на небольшие, четко очерченные части. Чтобы побороть сложность, мы должны абстрагироваться от мелких деталей. В этом смысле классы представляют собой весьма удобный инструмент.

Классы позволяют проводить конструирование из полезных компонент, обладающих простыми инструментами, что дает возможность абстрагироваться от деталей реализации.

Данные и операции вместе образуют определенную сущность и они не «размазываются» по всей программе, как это нередко бывает в случае процедурного программирования.

Локализация кода и данных улучшает наглядность и удобство сопровождения программного обеспечения.

Инкапсуляция информации защищает наиболее критичные данные от несанкционированного доступа.

ООП дает возможность создавать расширяемые системы (extensible systems). Это одно из самых значительных достоинств ООП и именно оно отличает данный подход от традиционных методов программирования. Расширяемость (extensibility) означает, что существующую систему можно заставить работать с новыми компонентами, причем без внесения в нее каких-либо изменений. Компоненты могут быть добавлены на этапе выполнения.

Расширение типа (type extension) и вытекающий из него полиморфизм переменных оказываются полезными преимущественно в следующих ситуациях.

Обработка разнородных структур данных. Программы могут работать, не утруждая себя изучением вида объектов. Новые виды могут быть добавлены в любой момент.

Изменение поведения во время выполнения. На этапе выполнения один объект может быть заменен другим. Это может привести к изменению алгоритма, в котором используется данный объект.

Реализация родовых компонент. Алгоритмы можно обобщать до такой степени, что они уже смогут работать более, чем с одним видом объектов.

Доведение полуфабрикатов. Компоненты нет надобности подстраивать под определенное приложение. Их можно сохранять в библиотеке в виде полуфабрикатов (semifinished products) и расширять по мере необходимости до различных законченных продуктов.

Расширение каркаса. Независимые от приложения части предметной области могут быть реализованы в виде каркаса и в дальнейшем расширены за счет добавления частей, специфичных для конкретного приложения.

Многоразового использования программного обеспечения на практике добиться не удается из-за того, что существующие компоненты уже не отвечают новым требованиям. ООП помогает этого достичь без нарушения работы уже имеющихся клиентов, что позволяет нам извлечь максимум из многоразового использования компонент.

Мы сокращаем время на разработку, которое с выгодой может быть отдано другим проектам.

Компоненты многоразового использования обычно содержат гораздо меньше ошибок, чем вновь разработанные, ведь они уже не раз подвергались проверке.

Когда некая компонента используется сразу несколькими клиентами, то улучшения, вносимые в ее код, одновременно оказывают свое положительное влияние и на множество работающих с ней программ.

Если программа опирается на стандартные компоненты, то ее структура и пользовательский интерфейс становятся более унифицированными, что облегчает ее понимание и упрощает ее использование.

Недостатки ООП

Объектно-ориентированное программирование требует знания четырех вещей.

1) Необходимо понимать базовые концепции, такие как классы, наследование и динамическое связывание. Для программистов, уже знакомых с понятием модуля и с абстрактными типами данных, это потребует минимальных усилий. Для тех же, кто никогда не использовал инкапсуляцию данных, это может означать изменения мировоззрения и может отнять на изучение значительное количество времени.

2) Многоразовое использование требует от программиста познакомиться с большими библиотеками классов. А это может оказаться сложнее, чем даже изучение нового языка программирования. Библиотека классов фактически представляет собой виртуальный язык, который может включать в себя сотни типов и тысячи операций. В языке Smalltalk, к примеру, до того, как перейти к практическому программированию, нужно изучить значительную часть его библиотеки классов. А это тоже требует времени.

3) Проектирование классов — задача куда более сложная, чем их использование. Проектирование класса, как и проектирование языка, требует большого опыта. Это итеративный процесс, где приходится учиться на своих же ошибках.

4) Очень трудно изучать классы, не имея возможности их «пощупать». Только с приобретением мало-мальского опыта можно уверенно себя почувствовать при работе с использованием ООП.

Как мы видели, усилия на освоение базовых концепций невелики, но вот в случае библиотек классов и их использования они могут быть очень существенными.

Поскольку детали реализации классов обычно неизвестны, то программисту, если он хочет разобраться в том или ином классе, нужно опираться на документацию и на используемые имена. И время, которое было сэкономлено на том, что удалось обойтись без написания собственного класса, должно быть отчасти потрачено (особенно вначале освоения) на то, чтобы разобраться в существующем классе.

Документирование классов — задача более трудная, чем это было в случае процедур и модулей. Поскольку любой метод может быть переопределен, в документации должно говориться не только о том, что делает данный метод, но также и о том, в каком контексте он вызывается. Ведь переопределенные методы обычно вызываются не клиентом, а самим каркасом. Таким образом, программист должен знать, какие условия выполняются, когда вызывается данный метод. Для абстрактных методов, которые пусты, в документации должно даже говориться о том, для каких целей предполагается использовать переопределяемый метод.

В сложных иерархиях классов поля и методы обычно наследуются с разных уровней. И не всегда легко определить, какие поля и методы фактически относятся к данному классу. Для получения такой информации нужны специальные инструменты вроде навигаторов классов. Если конкретный класс расширяется, то каждый метод обычно сокращают перед передачей сообщения базовому классу. Реализация операции, таким образом, рассредоточивается по нескольким классам, и чтобы понять, как она работает, нам приходится внимательно просматривать весь код.

Методы, как правило, короче процедур, поскольку они осуществляют только одну операцию над данными. Зато количество методов намного выше. Короткие методы обладают тем преимуществом, что в них легче разбираться, неудобство же их связано с тем, что код для обработки сообщения иногда «размазан» по многим маленьким методам.

Абстракция данных ограничивает гибкость клиентов. Клиенты могут лишь выполнять те операции, которые предоставляет им тот или иной класс. Они уже лишены неограниченного доступа к данным. Причины здесь аналогичны тем, что вызвали к жизни использование высокоуровневых языков программирования, а именно, чтобы избежать непонятных программных структур.

Абстракцией данных не следует злоупотреблять. Чем больше данных скрыто в недрах класса, тем сложнее его расширять. Отправной точкой здесь должно быть не то, что клиентам не разрешается знать о тех или иных данных, а то, что клиентам для работы с классом этих данных знать не требуется.

Часто можно слышать, что ООП является неэффективным. Как же дело обстоит в действительности? Мы должны четко проводить грань между неэффективностью на этапе выполнения, неэффектиностью в смысле распределения памяти и неэффективностью, связанной с излишней универсализацией.

1) Неэффективность на этапе выполнения. В языках типа Smalltalk сообщения интерпретируются во время выполнения программы путем осуществления поиска их в одной или нескольких таблицах и за счет выбора подходящего метода. Конечно, это медленный процесс. И даже при использовании наилучших методов оптимизации Smalltalk-программы в десять раз медленнее оптимизированных C-программ.

В гибридных языках типа Oberon-2, Object Pascal и C++ посылка сообщения приводит лишь к вызову через указатель процедурной переменной. На некоторых машинах сообщения выполняются лишь на 10% медленнее, чем обычные процедурные вызовы. И поскольку сообщения встречаются в программе гораздо реже других операций, их воздействие на время выполнения влияния практически не оказывает.

Однако, существует другой фактор, который затрагивает время выполнения: это абстракция данных. Абстракция запрещает непосредственный доступ к полям класса и требует, чтобы каждая операция над данными выполнялась через методы. Такая схема приводит к необходимости выполнения процедурного вызова при каждом доступе к данным. Однако, когда абстракция используется только там, где она необходима (т.е. не из одной лишь прихоти), то замедление вполне приемлемое.

 

(2) Неэффективность в смысле распределения памяти. Динамическое связывание и проверка типа на этапе выполнения требуют по ходу работы информации о типе объекта. Такая информация хранится в дескрипторе типа, и он выделяется один на класс. Каждый объект имеет невидимый указатель на дескриптор типа для своего класса. Таким образом, в объектно-ориентированных программах требуемая дополнительная память выражается в одном указателе для объекта и в одном дескрипторе типа для класса.

3) Излишняя универсальность. Неэффективность может также означать, что программа имеет ненужные возможности. В библиотечном классе часто содержится больше методов, чем это реально необходимо. А поскольку лишние методы не могут быть удалены, то они становятся мертвым грузом. Это не воздействует на время выполнения, но влияет на возрастание размера кода.

Одно из возможных решений — строить базовый класс с минимальным числом методов, а затем уже реализовывать различные расширения этого класса, которые позволят нарастить функциональность.

Другой подход — дать возможность компоновщику удалять лишние методы.

Такие интеллектуальные компоновщики уже доступны для различных языков и операционных систем.

Программные части могут добавляться на этапе выполнения. Таким образом, нет надобности загружать всю программу целиком, а можно обойтись лишь теми ее частями, которые в данный момент необходимы. Как показала практика, это экономит гораздо больше кода, чем можно добиться при удалении лишних методов.

Таким образом, нельзя утверждать, что ООП вообще неэффективно.

Если классы используются лишь там, где это действительно необходимо, то потеря эффективности и на этапе выполнения и в смысле памяти сводится практически на нет.

 

 


 

 

Проектный раздел

 


Классы

Каждый автомобиль на автостраде – это картинка, которая движется. Имитация движения каждой картинки осуществляется с помощью классов. Каждый класс содержит информацию о модели автомобиля, размере картинки, скорости и о текущем положении на дороге. Для реализации проекта были созданы восемь классов: Car, Lancer, Coupe, Fit, Caldina, Cabriolet, Cruzak, Smart.

Базовый класс Car имеет следующие параметры:

1)protected:

short int model;- модель автомобиля

2) public:

short int speed; текущая скорость автомобиля

short int speed1; скорость №1

short int speed2; скорость №2

short int speed3; скорость №3

int X; текущее положения на дороге

int dl; длина картинки

int H; высота картинки

short int IndCrash; идентификатор аварии

3)методы:

Car(void) конструктор класса

virtual ~Car(void) деструктор класса

void Crash(void) «авария»

void OK(void) «исправление аварии»

int ShowModel(void) возвращает значение переменной model

 

Рассмотрим методы более подробно.

Car(void){

}

Конструктор базового класса. Он не является виртуальным, так как при создании объекта данного класса, мы напрямую вызываем конструктор другого класса – потомка. В конструкторах классов потомков объект получает все значение описанные выше в пунктах 1 и 2.

 

virtual ~Car(void)

{

}

Деструктор класса необходимо сделать виртуальным. Так как в противном случае буден вызван деструктор базового класса.

 

void Crash(void)

{

speed=0;

model=model+model*10;

}

Данный метод вызывается объектами классов при аварии двух и более автомобилей. Переменная, которая хранит значение текущей скорости обнуляется. Также меняется значение переменной, которая хранит модель автомобиля. При аварии двух и более автомобилей изменяется цвет автомобиля (по умолчанию цвет всех автомобилей серый, при аварии он изменяется на красный). На самом деле при аварии изменяется не цвет картинки, а изменяется сама картинка, то есть изменяется имя текущей картинки. Данный метод реализует подобную замену.

 

void OK(void) {

model=model/10;

}

Метод изменяет имя текущей картинки. То есть возвращает картинку, которая была текущей до вызов функции Crash.

 

int ShowModel(void) {

return model;

}

Возвращает значения переменной model. Этот метод необходим, так как переменная model является защищенной (protected).

 

 

Алгоритм

 

Для реализации постоянного движения на автостраде весь алгоритм будет помещен в бесконечный цикл for(;;).

1) for(;;)

2) создается объект класса Car. И к нему случайный образо выбирется один из конструкторов классов – потомков. Для того,чтобы исключить наложение двух картинок автмобилей друг на друга, до создания объекта следует выполнит проверку, нет ли рядом недавно созданных объектов.

3) для эффекта паралелльного, независимого движения автомобилей нам понадобится структура – контейнер, в котором будут хранится все объекты базового класса. Лучше всего для данной задачи подойдет такая структура как очередь.

В данной проекте для реализации контейнера была использована стандартная библиотека шаблонов – «STL». Но так как в «STL» очередб не допускает прямого обращения к каждому своему элементу, в альтернативу был взят динамческий массив «Vector».

4)затем для каждого элемента выбранного контейнера (каждый элемент – это объект класса «Car») следует:

1. проверка условий на аварию

2. изменение текущей позиции(измениение значения переменной X)

3. прорисовка картинки по текущим координатам.

4. выбор текущей скорости

5. каждый объект при определенном моменте времени заканчивает свое движение. Для того чтобы наш контейнер не заполнялся, необходимо ввести усовие завершение движения и при его выполнении удалить ненужный объект.

 


 

 

Экспериментальный раздел


 

Описание программы

 

Данная программа реализована в среде Microsoft Visual Studio, на языке с++, проект Windows Forms Application.

Описание программы начнем с ее внешнего вида на примере. При запуске программы появляется окно (форма):

Рисунок 1- начало работы программы

 

Кнопка «start» служит для запуска программы.

Параметр N – вероятность появления нового автомобиля в определенный момент времени равна 1/N. Момент времени в данном случае одна итерация цикла for(;;).

Параметр distance – минимальное безопасное расстояние между автомобилями.

Параметр time – время задержки при аварии (количество итераций цикла for(;;)).

 

Пример работы программы

 

Рисунок 2 - пример работы программы

 

 

Рисунок 3 – пример аварии

 

 


 

Заключение

 

 


 

Классы нашли свое место в большинстве современных языков программирования. Одно лишь это говорит о том, что им суждено остаться. Классы в самом ближайшем будущем войдут в стандартный набор концепций для каждого программиста, точно так же, как многие сегодня применяют динамические структуры данных и рекурсию, которые двадцать лет назад были также в диковинку. В то же время классы — это просто еще одна новая конструкция наряду с остальными. Нам нужно узнать, для каких ситуаций они подходят, и только здесь мы и будем их использовать. Правильно выбрать инструмент для конкретной задачи — обязательно для каждого мастерового и в еще большей степени для каждого инженера.

ООП ввергает многих в состояние эйфории. Пестрящая тут и там реклама сулит нам невероятные вещи, и даже некоторые исследователи, похоже, склонны рассматривать ООП как панацею, способную решить все проблемы разработки программного обеспечения. Со временем эта эйфория постепенно уляжется. И после периода разочарования люди, быть может, перестанут уже говорить об ООП, точно также как сегодня вряд ли от кого можно услышать о структурном программировании. Но классы будут использовать как нечто само собой разумеющееся, и мы сможем, наконец, понять, что они собой представляют: просто компоненты, которые помогают строить модульное и расширяемое программное обеспечение.

 

 


 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-11-11 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: