Объектно-ориентированный анализ и программирование. План лекций
Содержание
Литература
Bertrand Meyer. Object-Oriented Software Construction (2nd edition), 1997.
Booch et al. Object-Oriented Analysis and Design with Applications (3rd Edition), 2007.
Gamma et al. Design Patterns: Elements of Reusable Object-Oriented Software, 1994.
ООП
Симула, абстракция данных.
Определение Кэя (2003): «Для меня ООП означает только обмен сообщениями, сохранение, защита и скрытие состояния-процесса, и экстремально позднее связывание всего. Так можно сделать в Смолтоке и в Лиспе. Возможно, есть и другие системы, которые позволяют это, но я о них не знаю.»
Взаимодействующие вычислительные узлы, отправка сообщений, управление состоянием.
Классы, объекты. Идентификация, состояние, поведение. Инкапсуляция, полиморфизм, наследование.
История
Парадигмы ЯП. Императивное → структурное → ООП.
Lisp, сборка мусора (1959). 1960-е. Структурное и процедурное программирование (ALGOL).
ООП. Кри́стен Ню́горд и Оле-Йохан Даль. Simula (1967)
PARC. Alan Kay. Smalltalk (1969, 1972, 1980), влияние Лиспа. Передача сообщений, «утиная» типизация.
Динамическая типизация: Smalltalk → Self, Python, Ruby.
Objective-C (1983) — Си дополненный передачей сообщений в стиле Смолтока.
Статическая типизация: Simula → Ada, C++ (1983), Eiffel (1986), Java (1991).
ООП на основе прототипов: Self (1987) → JavaScript (1995).
ООП с множественной диспетчеризацией (CLOS).
Абстрактные типы данных
Пример со стэком (Мейер).
- ADT. Типы. Универсализация (обобщение).
- Функции. Аппликативное против императивного. Запросы, команды, конструкторы.
- Аксиомы.
- Частичные функции, предусловия.
TYPES • STACK [G] FUNCTIONS • put: STACK [G] × G → STACK [G] • remove: STACK [G] /→ STACK [G] • item: STACK [G] /→ G • empty: STACK [G] → BOOLEAN • new: STACK [G] AXIOMS For any x: G, s: STACK [G] A1 • item (put (s, x)) = x A2 • remove (put (s, x)) = s A3 • empty (new) A4 • not empty (put (s, x)) PRECONDITIONS • remove (s: STACK [G]) require not empty (s) • item (s: STACK [G]) require not empty (s)
Пример выражения:
item (remove (put (remove (put (put ( remove (put (put (put (new, x1), x2), x3)), item (remove (put (put (new, x4), x5)))), x6)), x7)))
Класс — это абстрактный тип данных, снабженный некоторой (возможно частичной) реализацией.
Отложенные (абстрактные) и эффективные классы.
Классы
- Имя — обычно существительное (возможно, полученное в результате номинализации).
- экземпляры — объекты,
- поля — состояние,
- методы — поведение,
- инварианты.
Класс определяет тип объектов. Тип: возможные значения, операции, представление в памяти. Абстрактные типы. Интерфейс и реализация. Инкапсуляция. Позднее связывание и полиморфизм: ситуативный (ad-hoc), параметрический (обобщенное программирование), полиморфизм подтипов.
Методы. Модификаторы доступа. Команды и запросы. Доступ к атрибутам, UAP.
Отношения: композиционные и иерархические (наследование). Метаклассы (класс является объектом).
Отношения классов в UML.
Объекты
Тип. Идентичность и состояние. Изменяемость. Логическое и физическое состояние объекта.
Объекты-значения (value objects) и объекты-ссылки (reference objects).
Идентичность объекта.
Эквивалентность и хэш код.
Объектный граф (граф ссылок).
Наследование
- наследуемые элементы языка
- наследование и подтипы
- принцип подстановки Барбары Лисков
- номинальная и структурная системы типов
- переопределение и повторное использование
- дифференциальное наследование
- статичность и единственность
- composition over inheritance
- Проблема круг-эллипс. Решения путем изменения модели:
- успех/неудача или возврат нового значения;
- ослабить требования к Эллипсу;
- смена типа;
- предусловие Ellipse.stretchable;
- абстрактный класс RoundObject;
- убрать наследование, Circle.toEllipse();
- объединить классы;
- обратное наследование;
- неизменяемость;
- MutableEllipse.
Person, Prisoner, FreePerson.
- Множественное наследование
- проблема ромба
- примеси и типажи (Traits: Composable Units of Behaviour)
- наследование интерфейсов
- методы по умолчанию в Java 8
Примеси и типажи
Примеры из Traits: Composable Units of Behaviour
Типаж:
- предоставляет множество методов, реализующих поведение;
- требует множество методов, параметризующих реализуемое поведение;
- не определяет полей и не может получать доступ к полям класса;
- классы и типажи могут состоять из других типажей;
- не влияет на семантику класса (все равно, что предоставляемые методы были бы реализованы в классе непосредственно);
- не влияет на семантику типажа: составной типаж эквивалентен простому типажу, содержащему те же методы.
Реализация и производительность
- позднее связывание
- виртуальные методы
- ненаследуемые классы и непереопределяемые методы
- JIT и оптимизация
- примитивные типы
- управление памятью
- сборка мусора
- подсчет ссылок
- проблема циклических ссылок
- слабые ссылки
- сборка мусора
Процесс
Нет готовых рецептов. Жизненный цикл разработки. Макропроцесс.
Стили макропроцесса. Итеративный и поступательный. Водопадный.
Требования → Анализ и проектирование → Реализация → Тестирование → Развертывание → (следующая итерация)
Анализ и проектирование (микропроцесс)
(требования) → Анализ → (начальное решение) → Проектирование → спецификация, допускающая эффективную реализацию.
Задача | Решение | |
---|---|---|
Абстрактное | Модель анализа | Архитектура |
Конкретное | Конкретная задача | Реализация |
- OOA: требования → модель.
- ООD: модель → архитектура.
Расширяемость и повторное использование. Требования к методу модульного проектирования (Мейер, с. 40):
- Декомпозиция
- Комбинируемость
- Понятность
- Непрерывность
- Защита модулей
Сравнение ОО подхода и разработки сверху-вниз (Мейер, с. 104).
Анализ и проектирование
- идентификация элементов
- определение взаимодействий между элементами
- определение отношений между элементами
- определение семантики элементов
Анализ — создание описания задачи
Не обязательно с целю создания ПО.
Goals of performing analysis (Meyer)
- To understand the problem or problems that the eventual software system, if any, should solve.
- To prompt relevant questions about the problem and the system.
- To provide a basis for answering questions about specific properties of the problem and system.
- To decide what the system should do.
- To decide what the system should not do.
- To ascertain that the system will satisfy the needs of its users, and define acceptance criteria (especially when the system is developed for an outside customer under a contractual relationship).
- To provide a basis for the development of the system.
Модель поведения. Что делает система, а не как. (Буч)
- «В центре внимания анализа находится поведение, а не форма.» (Буч)
- На этапе анализа достаточно описать все основные аспекты поведения.
Или с чем она это делает?
- «Ask not first what the system does: ask what it does it to!» (Мейер)
Использование ОО для моделирования (Мейер, с. 907).
Поиск и исключение классов (Мейер, раздел 22, с. 719).
- «Лифт закрывает двереь перед началом движения на следующий этаж».
- Лифт? Дверь? Этаж?
- «Каждый раз, когда лифт перемещается между этадами, должна создаваться запись в базе данных.»
- Повторное использование известных абстракций.
- «Главная ошибка» (Мейер) — выделение классов-процедур вместо классов-абстракций данных.
- Классы, представляющие абстрактные структурные свойства (имена — прилагательные).
- Классы, представляющие абстрактные действия (команды).
- Классы без команд
- объекты из внешних источников,
- facility inheritance: общие наследуемые элементы (например, набор констант),
- аппликативные классы.
- Кортежи для простой группировки значений.
- Смешанные абстракции.
Типичный правильный класс:
- Ясная абстракция.
- Имя класса — имя существительное или прелагательное, точно характеризующее абстракцию.
- Представляет множество возможных объектов-экземпляров.
- Несколько запросов для выяснения свойств экземпляра.
- Несколько команд для изменения состояния экземпляра.
- Формально или неформально заданные абстрактные свойства: инварианты, предусловия, постусловия.
Классы
- анализа (модель внешней системы: Person, Paragraph),
- физические объекты и абстрактные понятия,
- проектирования (особенность архитектуры: Command, State),
- накопленный опыт, шаблоны проектирования,
- повторное использование,
- реализиации (требуется для реализации алгоритмов: LinkedList),
- использование абстрактных классов структур данных.
Пример с программой тебепередач (Мейер, с. 908).
Представления анализа:
- формальный текст (код),
- диаграмма,
- текст.
Архитектура и компоненты. Уровни абстракции
Идентификация элементов
- анализ — нахождение элементов,
- проектирование — изобретение элементов.
Определение взаимодействия
- от кратких описаний до интерфейсов.
Определение отношений.
- формализация разделения ответственности между элементами,
- ассоциация, аггрегация, композиция,
- направленность отношений,
- кардинальность отношений,
- выделение общей структуры и поведения.
Определение семантики.
- обязанности элемента,
- состояния элемента,
- наследование и делегирование.
Хорошая архитектура:
- многоуровневая система абстракций,
- четкая граница между интерфейсом и реализацией на каждом уровне абстракции,
- простота: общее поведение достигается общими абстракциями и механизмами.
Проектирование
Основные принципы:
- программирование на основе интерфейса, а не реализации,
- повторное использование функциональности,
- внутреннее, инструментарий, каркас,
- композиция объектов предпочтительнее наследования,
- делегирование, как альтернатива наследованию,
- предполагать изменения.
Факторы, ограничивающие гибкость архитектуры и приводящие к перепроектированию:
- явное указание класса при создании объекта,
- зависимость от аппаратной или программной платформы,
- зависимость от представлений и реализаций объектов,
- зависимость от конкретных алгоритмов,
- сильная зависимость между объектами (tight coupling),
- использование наследования вместо композиции,
- невозможность изменить внешние классы.
Инверсия управления и внедрение зависимости.
Шаблоны проектирования
Gamma et al. Design Patterns: Elements of Reusable Object-Oriented Software, 1994.
GoF: Эрих Гамма (Erich Gamma), Ричард Хелм (Richard Helm), Ральф Джонсон (Ralph Johnson), Джон Влиссидс (John Vlissides)
Шаблоны проектирования — описания взаимодействующих объектов и классов, нацеленные на решение общих проблем проектирования в определенном контексте.
Польза шаблонов:
- обобщение опыта,
- унификация словаря решений проектирования.
- в GoF:
- выявление неочевидных абстракций и объектов,
- определение детальности разбиения на объекты,
- определение интерфейсов.
Критика:
- шаблоны — недостающие возможности ЯП,
- зависимость шаблонов от языка,
- повтор решений вместо реализации один раз,
- чрезмерное усложнение (overengineering).
Элементы шаблона: имя, задача, решение, последствия.
Описание шаблона:
- имя и классификация,
- назначение,
- альтернативные названия,
- мотивация,
- применимость,
- структура,
- участники,
- взаимодействие,
- последствия,
- особенности реализации,
- пример кода,
- примеры использования,
- связанные шаблоны.
Категории:
- порождающие, структурные, поведенческие;
- дополнительно (нет в GoF): шаблоны параллельного программирования.
Антипаттерны
http://wiki.c2.com/?AntiPatternsCatalog https://sourcemaking.com/antipatterns/software-development-antipatterns http://sahandsaba.com/nine-anti-patterns-every-programmer-should-be-aware-of-with-examples.html
- Anemic domain model (Малокровная модель) Domain Model and Service Layer
- DataClump
- BaseBean (Наследование от вспомогательного класса) IS-A vs HAS-A
- Call super Решение: шаблонные методы и зацепки.
- Circle-ellipse problem (наследование ссылочных типов на основе подтипов-значений)
- Circular dependency
- Constant interface
- God object
- Object cesspool
- Object orgy (доступ к внутреннему состоянию объекта)
- доступ к полям
- передача внутреннего состояния другим объектам в аргументах
- Poltergeists
- Sequential coupling
- Yo-yo problem