Гради Буч - Объектно-ориентированный анализ и проектирование с примерами приложений на С++ (1158635), страница 32
Текст из файла (страница 32)
Взаимосвязь классов и объектовОтношения между классами и объектамиКлассы и объекты - это отдельные, но тесно связанные понятия. Вчастности, каждый объект является экземпляром какого-либо класса; классможет порождать любое число объектов. В большинстве практическихслучаев классы статичны, то есть все их особенности и содержаниеопределены в процессе компиляции программы. Из этого следует, что любойсозданный объект относится к строго фиксированному классу.
Сами объекты,напротив, в процессе выполнения программы создаются и уничтожаются.В качестве примера рассмотрим классы и объекты для задачиуправления воздушным движением. Наиболее важные абстракции в этойсфере - самолеты, графики полетов, маршрут и коридоры в воздушномпространстве. Трактовка этих классов объектов по самому их определениюдостаточно статична. Иначе невозможно было бы построить никакогоприложения, использующего такие общепонятные факты, как то, чтосамолеты могут взлетать, летать и приземляться, а также что никакие двасамолета не должны находиться одновременно в одной и той же точке.Объекты же этих классов, напротив, динамичны. Набор маршрутовполетов сменяется не очень часто. Существенно быстрее изменяетсямножество самолетов, находящихся в полете.
Частота, с которой самолетызанимают и покидают воздушные коридоры, еще выше.Роль классов и объектов в анализе и проектированииНа этапе анализа и ранних стадиях проектирования решаются двеосновные задачи:• Выявление классов и объектов, составляющих словарь предметнойобласти.• Построение структур, обеспечивающих взаимодействие объектов,при котором выполняются требования задачи.В первом случае говорят о ключевых абстракциях задачи(совокупность классов и объектов), во втором - о механизмах реализации(совокупность структур).На ранних стадиях внимание проектировщика сосредоточивается навнешних проявлениях ключевых абстракций и механизмов. Такой подходсоздает логический каркас системы: структуры классов и объектов. Напоследующих фазах проекта, включая реализацию, внимание переключаетсяна внутреннее поведение ключевых абстракций и механизмов, а также ихфизическое представление.
Принимаемые в процессе проектированиярешения задают архитектуру системы: и архитектуру процессов, иархитектуру модулей.3.6. Качество классов и объектовИзмерение качества абстракцииПо мнению Ингалса "для построения системы должен использоватьсяминимальный набор неизменяемых компонент; сами компоненты должныбыть по возможности стандартизованы и рассматриваться в рамках единоймодели" [51]. Применительно к объектно-ориентированному проектированиютакими компонентами являются классы и объекты, отражающие ключевыеабстракции системы, а единство обеспечивается соответствующимимеханизмами реализации.Опыт показывает, что процесс выделения классов и объектов являетсяпоследовательным, итеративным.
За исключением самых простых задач спервого раза не удается окончательно выделить и описать классы. В главах 4 и7 показано, как в процессе работы сглаживаются противоречия, возникающиепри начальном определении абстракций. Очевидно, такой процесс связан сдополнительными затратами на перекомпиляцию, согласование и внесениеизменений в проект системы. Очень важно, следовательно, с самого начала повозможности приблизиться к правильным решениям, чтобы сократить числопоследующих шагов приближения к истине. Для оценки качества классов иобъектов, выделяемых в системе, можно предложить следующие пятькритериев:• зацепление• связность• достаточность• полнота• примитивность.Термин зацепление взят из структурного проектирования, но в болеевольном толковании он используется и в объектно-ориентированномпроектировании.
Стивенс, Майерс и Константайн определяют зацепление как"степень глубины связей между отдельными модулями. Систему с сильнойзависимостью между модулями гораздо сложнее воспринимать имодифицировать. Сложность системы может быть уменьшена путемуменьшения зацепления между отдельными модулями" [52]. Примернеправильного подхода к проблеме зацепления привел Пейдж-Джонс, описавмодульную стереосистему, в которой источник питания размещен в одной иззвуковых колонок [53].Кроме зацепления между модулями в объектно-ориентированноманализе, существенно зацепление между классами и объектами. Существуетопределенное противоречие между явлениями зацепления и наследования. Содной стороны, желательно избегать сильного зацепления классов; с другойстороны, механизм наследования, тесно связывающий подклассы ссуперклассами, помогает выгодно использовать сходство абстракций.Понятие связности также заимствовано из структурногопроектирования.
Связность - это степень взаимодействия между элементамиотдельного модуля (а для OOD еще и отдельного класса или объекта),характеристика его насыщенности. Наименее желательной является связностьпо случайному принципу, когда в одном классе или модуле собираютсясовершенно независимые абстракции. Для примера можно вообразить класс,соединяющий абстракции собак и космических аппаратов. Наиболеежелательной является функциональная связность, при которой все элементыкласса или модуля тесно взаимодействуют в достижении определенной цели.Так, например, класс Dog будет функционально связным, если он описываетповедение собаки, всей собаки, и ничего, кроме собаки.К идеям зацепления и связности тесно примыкают понятиядостаточности, полноты и примитивности.
Под достаточностьюподразумевается наличие в классе или модуле всего необходимого дляреализации логичного и эффективного поведения. Иначе говоря, компонентыдолжны быть полностью пригодны к использованию. Для примерарассмотрим класс set (множество). Операция удаления элемента из множествав этом классе, очевидно, необходима, но будет ошибкой не включить в этоткласс и операцию добавления элемента. Нарушение требования достаточностиобнаруживается очень быстро, как только создается клиент, использующийабстракцию. Под полнотой подразумевается наличие в интерфейсной частикласса всех характеристик абстракции. Идея достаточности предъявляет кинтерфейсу минимальные требования, а идея полноты охватывает все аспектыабстракции.
Полнотой характеризуется такой класс или модуль, интерфейскоторого гарантирует все для взаимодействия с пользователями. Полнотаявляется субъективным фактором, и разработчики часто ею злоупотребляют,вынося на верх такие операции, которые можно реализовать на более низкомуровне. Из этого вытекает требование примитивности. Примитивнымиявляются только такие операции, которые требуют доступа к внутреннейреализации абстракции. Так, в примере с классом set операция Add(добавление к множеству элемента) примитивна, а операция добавлениячетырех элементов не будет примитивной, так как вполне эффективнореализуется через операцию добавления одного элемента.
Конечно,эффективность тоже вещь субъективная. Операция, которая требует прямогодоступа к структуре данных, примитивна по определению. Операция, котораяможет быть описана в терминах существующих примитивных операций, ноценой значительно больших вычислительных затрат, также являетсякандидатом на включение в разряд примитивных.20Как выбрать операции?Функциональность. Описание интерфейса класса или модуля трудная работа. Обычно первое приближение делается, исходя изструктурного смысла класса, а затем, когда появляются клиенты класса,интерфейс уточняется, модифицируется и дополняется. В частности можетвозникнуть потребность в создании новых классов или в изменениивзаимодействия существующих.В пределах каждого класса принято иметь только примитивныеоперации, отражающие отдельные аспекты поведения. Такие методыназываются точными.
Принято также отделять методы, не связанные междусобой. Это облегчает образование подклассов с переопределением поведения.Решение о количестве методов может быть обусловлено двумя причинами:20Примером может служить операция добавления к множеству произвольного числаэлементов (а не обязательно четырех). - Примеч. ред.описание поведения в одном методе упрощает интерфейс, но усложняет иувеличивает размеры самого метода; расщепление метода усложняетинтерфейс, но делает каждый из методов проще.