ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ АНАЛИЗ
Одной из основных задач, решаемых на этапе анализа и ранних стадиях проектирования, является выявление ключевых абстракций задачи – классов и объектов, составляющих словарь предметной области.
На ранних стадиях внимание проектировщика сосредоточивается на внешних проявлениях ключевых абстракций. Такой подход создает логический каркас системы: структуры классов и объектов. На последующих фазах внимание переключается на внутреннее поведение ключевых абстракций, а также их физическое представление.
Выделим следующие способы проведения объектно-ориентированного анализа:
– классический подход;
– анализ поведения;
– анализ предметной области;
– анализ вариантов;
– CRC-карточки;
– неформальное описание.
Классический подход к классификации предполагает, что все вещи, обладающие некоторым свойством или совокупностью свойств, формируют некоторую категорию. Причем наличие этих свойств является необходимым и достаточным условием, определяющим категорию.
Например, студент – это категория: каждый человек или является студентом, или не является, и этого признака достаточно для решения вопроса, к какой категории принадлежит тот или иной индивидуум. С другой стороны, высокие люди не определяют категории, если, конечно, мы специально не уточним критерий, позволяющий четко отличать высоких людей от невысоких.
Таким образом, классический подход в качестве критерия похожести объектов использует родственность их свойств. В частности, объекты можно разбивать на непересекающиеся множества в зависимости от наличия или отсутствия некоторого признака.
Какие конкретно свойства надо принимать во внимание? Это зависит от цели классификации. Например, цвет автомобиля надо зафиксировать в задаче учета продукции автозавода, но он не интересен программе, которая управляет уличным светофором. Поэтому нет абсолютного критерия классификации, одна и та же структура классов может подходить для одной задачи и не годиться для другой.
При данном подходе кандидатами в классы и объекты могут быть выбраны:
– осязаемые предметы (автомобили, датчики);
– роли (учитель, политик);
– события (посадка на Марс, запрос);
– взаимодействие (заем, встреча).
Анализ поведения сосредоточивается на динамическом поведении как на первоисточнике объектов и классов. Классы формируются на основе групп объектов, демонстрирующих сходное поведение.
Напомним, что ответственностью объекта называют совокупность всех услуг, которые он может предоставлять по всем его контрактам. В результате анализа объединяют объекты, имеющие сходные ответственности и строят иерархию классов, в которую каждый подкласс, выполняя обязательства суперкласса, привносит свои дополнительные услуги.
До сих пор мы неявно имели в виду единственное разрабатываемое нами приложение. Но иногда в поисках полезных и уже доказавших свою работоспособность идей полезно обратиться сразу ко всем приложениям в рамках данной предметной области. Анализ данной предметной области может указать на ключевые абстракции, оказавшиеся полезными в сходных системах. Анализ предметной области – это попытка выделить те объекты, операции и связи, которые эксперты данной области считают наиболее важными.
Анализ включает следующие этапы:
– построение скелетной модели предметной области при консультациях с экспертами в этой области;
– изучение существующих в данной области систем и представление результатов в стандартном виде;
– определение сходства и различий между системами при участии экспертов;
– уточнение общей модели для приспособления к нуждам конкретной системы.
Анализ области можно вести относительно аналогичных приложений (вертикально) или относительно аналогичных частей одного и того же приложения (горизонтально).
В роли эксперта часто выступает пользователь системы, например, инженер или диспетчер. Он не обязательно должен быть программистом, но ему должны быть хорошо знакомы исследуемая проблема и ее язык.
Анализ вариантов – это подход, который можно успешно сочетать с первыми тремя, делая их применение более упорядоченным.
Вариант применения – это частный пример, сценарий или образец использования, начинающийся с того, что пользователь системы инициирует операцию или последовательность взаимосвязанных событий.
Пользователи, эксперты и разработчики перечисляют сценарии, наиболее существенные для работы системы (пока не углубляясь в детали). Затем они тщательно прорабатывают сценарии, раскладывая их по кадрам. При этом устанавливается, какие объекты участвуют в сценарии, каковы обязанности каждого объекта и как они взаимодействуют в терминах операций. Далее набор сценариев расширяется, чтобы учесть исключительные ситуации и вторичное поведение.
CRC-карточки – Class-Responsibilities-Collaborators (Класс-Ответственности-Сотрудники) – это простой и эффективный способ анализа сценариев.
Сотрудник – это другой класс, который взаимодействует с данным для обеспечения некоего общего набора поведений.
На обычных карточках небольшого размера сверху пишут название класса, снизу в левой половине – за что он отвечает, снизу в правой половине – с кем он сотрудничает.
На рис. 5.1 приведен вид CRC-карточки для класса Stack.
Рис. 5.1. CRC-карточка для класса Stack
Разработчики по ходу анализа сценария заводят по карточке на каждый обнаруженный класс и дописывают в нее новые пункты.
Карточки можно раскладывать так, чтобы представить формы сотрудничества объектов. С точки зрения динамики сценария их расположение может показать поток сообщений между объектами, с точки зрения статики они представляют иерархии классов.
Согласно методу неформального описания надо описать задачу или ее часть на обычном разговорном языке, а потом подчеркнуть существительные и глаголы. Существительные – кандидаты на роль классов, а глаголы могут стать именами операций.
Подход прост, однако он весьма приблизителен и непригоден для сколько-нибудь сложных проблем. Кроме того, человеческий язык не является точным средством выражения.
Некоторым существительным больше соответствуют не классы, а, например, признаки или свойства объектов (имя, возраст, вес, адрес и т.п.) или даже имена операций ("телефонный вызов" вряд ли означает какой-либо класс).
Рассмотрим вопросы поиска, выбора и уточнения ключевых абстракций.
Самая главная ценность ключевых абстракций заключается в том, что они определяют границы нашей проблемы: выделяют то, что входит в нашу систему и поэтому важно для нас, и устраняют лишнее. Задача выделения таких абстракций специфична для проблемной области. Правильный выбор объектов зависит от назначения приложения и степени детальности обрабатываемой информации.
Определение ключевых абстракций включает в себя два процесса: открытие и изобретение. Мы открываем абстракции, слушая специалистов по предметной области: если эксперт про нее говорит, то эта абстракция обычно действительно важна. Изобретая, мы создаем новые классы и объекты, не обязательно являющиеся частью предметной области, но полезные при проектировании или реализации системы. Например, пользователь банкомата говорит "счет, снять, положить"; эти термины – часть словаря предметной области. Разработчик системы использует их, но добавляет свои, такие, как "база данных", "список", "очередь" и т.д. Эти ключевые абстракции созданы уже не предметной областью, а проектированием. Наиболее мощный способ выделения ключевых абстракций – сведение задачи к уже известным классам и объектам.
Определив новые абстракции, мы должны найти их место в контексте уже существующих классов и объектов. Не стоит пытаться делать это строго сверху вниз или снизу вверх, поскольку трудно сразу расположить классы и объекты на правильных уровнях абстракции. Иногда, найдя важный класс, мы можем передвинуть его вверх в иерархии классов, тем самым увеличивая степень повторности использования кода. Аналогично, можно прийти к выводу, что класс слишком обобщен, и это затрудняет наследование.
Кроме того, по ходу работы возможно следующее:
– выделить излишек ответственности в новый класс;
– перенести ответственность с одного большого класса на несколько более детальных классов;
– передать часть обязанностей другому классу.