Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ООП.doc
Скачиваний:
23
Добавлен:
08.11.2018
Размер:
1.4 Mб
Скачать
  1. Основы объектно-ориентированного анализа и проектирования

Работу над программным проектом можно разделить на несколько этапов:

  • анализ предметной области и требований к программному продукту;

  • проектирование, включающее в себя как проектирование внутренней структуры программы, так и пользовательского интерфейса;

  • программирование – то есть написание кода.

В рамках объектно-ориентированного подхода выделяют объектно-ориентированное программирование, объектно-ориентированное проектирование и объектно-ориентированный анализ.

Объектно-ориентированное программирование – это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.

В данном определении можно выделить три части:

  1. ООП использует в качестве базовых элементов объекты, а не алгоритмы;

  2. Каждый объект является экземпляром какого-либо класса;

  3. Классы организованы иерархически.

Объектно-ориентированное проектирование – это методология проектирования, соединяющая в себе процесс объектной декомпозиции и приемы представления логической и физической, а также статической и динамической моделей проектируемой системы.

В данном определении содержатся две важные части объектно-ориентированного проектирования:

  1. Основывается на объектно-ориентированной декомпозиции;

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

Объектно-ориентированное проектирование отличается от структурного именно использованием объектно-ориентированной декомпозиции.

Для объектно-ориентированного проектирования существуют несколько вариантов нотаций. Наиболее известны – нотация Буча, технология объектного моделирования (OMT, Object Modeling Technology) и унифицированный язык моделирования (UML, Unified Modeling Language), который был разработан на основе двух предыдущих. В настоящее время UML наиболее распространен, принят многими производителями и комитетами по стандартам. Именно на нем основана методология проектирования ПО RUP (Rational Unified Process), разработанная компанией Rational Software. Первая версия UML – UML 1 появилась в январе 1997 г. В настоящее время все еще происходит процесс развития и усовершенствования UML.

Объектно-ориентированный анализ – это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области.

Объектно-ориентированная модель

Концептуальной основой объектно-ориентированного подхода является объектная модель. В нее входят четыре главных элемента:

  • абстрагирование

  • инкапсуляция

  • модульность

  • иерархия.

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

И три дополнительных элемента:

  • типизация

  • параллелизм

  • сохраняемость (устойчивость)

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

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

Разделение между существенными и несущественными особенностями называют барьером абстракции.

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

Выбор правильного набора абстракций для заданной предметной области представляет собой главную задачу объектно-ориентированного проектирования.

Существуют различные варианты абстракций. Они перечислены начиная от наиболее полезных к наименее:

  • абстракция сущности – объект представляет собой полезную модель некой сущности в предметной области

  • абстракция поведения – объект состоит из обобщенного множества операций

  • абстракция виртуальной машины – объект группирует операции, которые либо вместе используются более высоким уровнем управления, либо сами используют некоторый набор операций более низкого уровня

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

Нужно стараться строить абстракции сущности, так как они прямо соответствуют сущностям предметной области.

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

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

Инкапсуляция – это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение.

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

Модульность – это разделение программы на фрагменты, которые компилируются по отдельности, но могут устанавливать связи с другими модулями. Связи между модулями – это их представления друг о друге. Таким образом, модульность и инкапсуляция имеют много общего. В разных языках программирования модульность поддерживается по-разному. Например в С/C++ традиционным является помещение интерфейсной части модулей в отдельные файлы с расширением .h. Реализация – в файл .c или .cpp. Но это исключительно договоренность и не является требованием самого языка. В Object Pascal структура модуля оговорена строго.

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

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

В традиционном структурном проектировании модульность – это искусство раскладывать подпрограммы по кучкам так, что бы в одну кучку попали подпрограммы, использующие друг друга, или используемые вместе. В ООП ситуация несколько иная – необходимо физически разделить классы и объекты, составляющие логическую структуру проекта.

Общие рекомендации:

  • структура модуля должна быть достаточно простой для восприятия

  • реализация каждого модуля не должна зависеть от реализаций других модулей

  • должны быть приняты меры для облегчения процесса внесения изменений там, где они наиболее вероятны.

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

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

В процессе разделения системы на модули могут быть полезны следующие практические правила:

  • выделять в отдельные модули код, который будет использоваться повторно;

  • разделение на модули проводится в зависимости от того, кто будет их разрабатывать;

  • неоправданное увеличение числа модулей приведет к чрезмерному увеличению документации на них.

Иерархия – это упорядочивание абстракций, расположение их по уровням.

Основными видами иерархических структур, применительно к сложным системам, являются структура классов (иерархия быть чем-то) и структура объектов (иерархия быть частью чего-то).

Пример иерархии классов – наследование, которое еще называют иерархией обобщение-специализация.

Пример иерархии объектов – агрегация – включение одного объекта в другой.

Типизация – это способ защитится от использования объектов одного класса вместо другого, или, по крайней мере, управлять таким использованием.

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

Типизация бывает сильная и слабая. Язык С++ тяготеет к слабой типизации примитивных типов. Object Pascal напротив предоставляет для примитивных типов сильную типизацию. Тогда как для классов оба они ближе к сильной типизации. Присваивание переменных типа класс допустимо, если они одного типа или в направлении снизу вверх по типам.

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

Сохраняемость. Любой программный объект существует в памяти и живет во времени. Но здесь есть варианты:

  • промежуточные результаты вычисления выражений,

  • локальные переменные в вызове процедур,

  • глобальные переменные или динамически создаваемые данные,

  • данные, сохраняющиеся между сеансами выполнения программы,

  • данные, сохраняемые при переходе на новую версию программы,

  • данные, которые переживают программу.

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

Введение сохраняемости, как нормальной составной части объектно-ориентированного подхода приводит нас к объектно-ориентированным базам данных. На практике такие базы данных строятся на основе обычных моделей, например реляционной, но программист может ввести абстракцию объектно-ориентированного интерфейса, через который запросы к базе данных и другие операции выполняются в терминах объектов, время жизни которых превосходит время жизни отдельной программы. Кроме того, существуют объектно-ориентированные СУБД.

Сохраняемость – это способность объекта существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства.