8.14. ГИБРИДНЫЕ ТЕХНОЛОГИИ ПРОЕКТИРОВАНИЯ

8.14. ГИБРИДНЫЕ ТЕХНОЛОГИИ ПРОЕКТИРОВАНИЯ

8.14.1. Игнорирование классов

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

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

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

В точности так же происходит в случае иерархии классов с одним корнем, когда "важные" данные всплывают по направлению к базовому классу (рис. 8.16).

Рис. 8.16. Игнорирование классов и их наследования

8.14.2. Игнорирование наследования

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

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

8.14.3. Игнорирование статического контроля типов

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

Рассмотрим следующую аналогию: в физическом мире мы постоянно соединяем различные устройства, и существует кажущееся бесконечным число стандартов на соединения. Главная особенность этих соединений — они специально спроектированы таким образом, чтобы сделать невозможным соединение двух устройств, не рассчитанных на него, т. е. соединение должно быть сделано единственным правильным способом. Вы не можете подсоединить радиотрансляционный приемник к розетке с высоким напряжением. Если бы вы смогли сделать это, то сожгли бы приемник или сгорели сами.

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

На раннем этапе проектирования вполне достаточно простого утверждения:

Рис. 8.17. Игнорирование статического контроля типов

"Эти два устройства необходимо соединить", но скоро становится существенным, как именно следует их соединить: "Какие гарантии дает соединение относительно поведения устройств?" или "Возникновение каких ошибочных ситуаций возможно?", или "Какова приблизительная цена такого соединения?"

8.14.4. Гибридный проект

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

1) изучая объектно-ориентированное проектирование, программисты могут продолжать работать по технологии структурного программирования;

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

Рис. 8.18. Гибридный проект

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

ВЫВОДЫ

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

• Объектно-ориентированный подход помогает справиться с такими сложными проблемами, как:

— уменьшение сложности программного обеспечения;

— повышение надежности программного обеспечения;

— обеспечение возможности модификации отдельных компонентов программного обеспечения без изменения остальных его компонентов;

— обеспечение возможности повторного использования отдельных компонентов программного обеспечения.

• Методы объектно-ориентированного проектирования используют в качестве строительных блоков объекты.

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

• Наследование выполняет в ООП несколько важных функций:

— моделирует концептуальную структуру предметной области;

— экономит описания, позволяя использовать их многократно для задания разных классов;

— обеспечивает пошаговое программирование больших систем путем многократной конкретизации классов.

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

• Идеальный класс должен в минимальной степени зависеть от остального мира. Каждый класс имеет набор поведений и характеристик, которые его определяют.

• При перестройке иерархии классов применяются четыре процедуры:

1) расщепление класса на два и более;

2) абстрагирование (обобщение);

3) слияние;

4) анализ возможности использования существующих разработок.

• Разработка проекта начинается с составления функциональной модели.

• Объектная модель представляет статическую структуру проектируемой системы (подсистемы).

• Динамическая модель системы представляется диаграммой последовательности и диаграммой состояний объектов.

Контрольные вопросы

1. При решении каких проблем лучше использовать объектно-ориентированный подход?

2. Какие характеристики являются фундаментальными в объектно-ориентированном мышлении?

3. На каких принципах базируется объектная модель?

4. Что такое паттерн проектирования?

5. Какому паттерну соответствует динамический и статический контейнер А. Усова?

6. Какие преимущества дает объектная модель?

7. В чем заключаются преимущества инкапсуляции?

8. В чем заключается важность наследования?

9. Для чего полезен полиморфизм?

10. Что такое агрегирование объекта?

11. Из каких этапов состоит процесс построения объектной модели?

12. Каким образом взаимодействуют между собой объекты в программе?

13. Какие процедуры применяются при перестройке схемы наследования классов?

14. Почему так важен анализ функционирования системы?

15. В чем заключается удобство использования CRC-карточек?

16. Какие диаграммы используют в проектах средней сложности?