Шаг 57.
Унифицированный язык моделирования UML.
Идентификация основных абстракций

    На этом шаге рассмотрим основные абстракции и их идентификацию.

    Основная абстракция (key abstraction) — это класс или объект, входящий в словарь проблемной области. Главный смысл основных абстракций состоит в том, что они очерчивают границы задачи: подчеркивают элементы, входящие в систему и потому относящиеся к проекту, и отбрасывают избыточные сущности.

    Идентификация основных абстракций сильно зависит от предметной области. По мнению Голдберг (Goldberg), правильный выбор объектов зависит от цели приложения и глубины детализации обрабатываемой информации [Goldberg, A. 1984. Smalltalk-80: The Interactive Programming Environment. Reading, MA: Addison-Wesley, p. 77.]. Идентификация основных абстракций включает в себя два процесса: открытие и изобретение. Открытие позволяет распознавать абстракции, используемые экспертами предметной области, поскольку обычно они упоминают лишь важные абстракции [Thomas, D. May/June 1989. In Search of an Object-Oriented Development Process. Journal of Object-Oriented Programming vol. 2(1), p. 61.].

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

    Определив кандидатов на роли основных абстракций, необходимо оценить их соответствие критериям. Страуструп (Stroustrup) пишет, что программист должен ответить на несколько вопросов. Как создаются объекты данного класса? Можно ли копировать и/или уничтожать объекты данного класса? Какие операции можно выполнять над такими объектами? Если ответы на эти вопросы неудовлетворительны, то вполне вероятно, что соответствующее понятие слишком туманно, так что стоит еще раз продумать задачу, прежде чем приступать к программированию [Stroustrup, B. 1986. The C++ Programming Language. Reading, MA: Addison- Wesley, p. 7.].

    Идентифицировав новую абстракцию, необходимо найти ее место в иерархии уже существующих классов и объектов. Эту задачу невозможно решить только методом нисходящего или восходящего анализа. Халберт (Halbert) и О'Брайен (O'Brien) утверждают, что нет необходимости строить иерархию классов, начиная с суперкласса и дополняя ее подклассами. Обычно создаются несколько внешне разных типов, осознается их связь, затем их общие характеристики описываются в одном или нескольких суперклассах, и этот процесс повторяется несколько раз, пока не возникнет полный и корректный проект программы [Halbert, D., and O'Brien, P. September 1988. Using Types and Inheritance in Object-Oriented Programming. IEEE Software vol. 4(5), p. 75.]. Эта рекомендация является результатом эмпирических наблюдений, подтверждающих, что объектно-ориентированное проектирование представляет собой итерационный процесс.

    Классы и объекты должны находиться на соответствующем уровне абстракции: не слишком высоко и не слишком низко Разместить классы и объекты на правильных уровнях абстракции довольно трудно. Иногда, определив общий подкласс, проектировщик может передвинуть его вверх в структуре классов, увеличив степень его совместного использования. Этот процесс называется продвижением класса (class promotion) [Stroustrup, B. 1991. The C+ Programming Language. Second Edition. Reading, MA: Addison-Wesley, p. 377.]. Аналогично, может оказаться, что некий класс обладает слишком общими свойствами, что затрудняет наследование из-за большого семантического разрыва. Это явление называется конфликтом детализации (grainsize conflict) [Stefik and Bobrow. Object-Oriented Programming, p. 58.]. В обоих случаях необходимо выявить связанность или слабую связность абстракций, и разрешить конфликт.

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

  1. Объекты следует называть существительными: например, theSensor или shape.
  2. Классы следует называть обобщенными существительными: например, Sensors или Shapes.
  3. По возможности, выбранные имена должны соответствовать терминам, используемым экспертами предметной области.
  4. Операции, модифицирующие данные, следует называть активными глаголами: например, Draw или moveLeft.
  5. Имена операций выбора должны подразумевать запрос или состояние: extentOf или isOpen.
  6. Подчеркивание и заглавные буквы можно использовать по своему усмотрению. Внешний вид имен не важен — главное, чтобы программа не была противоречивой.

    На следующем шаге рассмотрим идентификацию механизмов.




Предыдущий шаг Содержание Следующий шаг