- •Введение
- •Как получить исходные тексты
- •Что требуется знать для чтения книги
- •Предисловие к первому изданию
- •Благодарности
- •1.3.Новая парадигма
- •Что читать дальше
- •Упражнения
- •2.7.3.Зацепление и связность
- •2.9. Выбор представления данных
- •Упражнения
- •Глава 3 Классы и методы
- •Упражнения
- •Глава 4 Сообщения, экземпляры и инициализация
- •Упражнения
- •Глава 5 Учебный пример: задача о восьми ферзях
- •Упражнения
- •Глава 6 Учебный пример: игра «Бильярд»
- •Упражнения
- •Глава 7 Наследование
- •7.6.Издержки наследования
- •Упражнения
- •Глава 8 Учебный пример: Пасьянс
- •8.4.1.Основание SuitPile
- •8.4.2.Колода DeckPile
- •Упражнения
- •9.1.1. «Быть экземпляром» и «включать как часть»
- •Упражнения
- •Глава 10 Подклассы и подтипы
- •Упражнения
- •Глава 11 Замещение и уточнение
- •Упражнения
- •Глава 12 Следствия наследования
- •Упражнения
- •Глава 13 Множественное наследование
- •13.1.Комплексные числа
- •Литература для дальнейшего чтения
- •Упражнения
- •Глава 14 Полиморфизм
- •Полиморфные переменные
- •Виртуальное и невиртуальное переопределение
- •Параметрическая перегрузка
- •Отложенные методы в C++
- •Обобщенные функции и шаблоны
- •Полиморфные переменные
- •Отложенные методы в Object Pascal
- •Полиморфные переменные
- •Отложенные методы в Objective-C
- •Полиморфные переменные
- •Отложенные методы в Smalltalk
- •Упражнения
- •Глава 15 Учебный пример: контейнерные классы
- •Упражнения
- •Глава 16 Пример: STL
- •Упражнения
- •Глава 17 Видимость и зависимость
- •Родственные экземпляры
- •Дружественные функции
- •Пространства имен
- •Постоянные члены
- •Упражнения
- •Глава 18 Среды и схемы разработки
- •18.1.1. Java API
- •Упражнения
- •19.5.Класс application
- •19.5.1.Класс button
- •Упражнения
- •Глава 20 Новый взгляд на классы
- •20.2.2.Класс Class
- •Упражнения
- •Глава 21 Реализация объектно-ориентированных языков
- •Литература для дальнейшего чтения
- •Упражнения
- •А.1. «Задача о восьми ферзях» на языке Apple Object Pascal
- •A.3. «Задача о восьми ферзях» на языке Java
- •A.3.1. HTML-файл для апплета Java
- •A.4. «Задача о восьми ферзях» на языке Objective-C
- •A.5. «Задача о восьми ферзях» на языке Smalltalk
- •Б.1. Версия без использования наследования
- •Б.2. Версия с использованием наследования
- •Глоссарий
converted to PDF by BoJIoc
17.4. Преднамеренное зацепление
Хотя, как правило, программисты стараются избегать зацепления между фрагментами кода, иногда оно полезно. Представьте себе, например, что вы моделируете некий динамический объект. Макет графически отображается в графическом окне (или окнах), которое должно непрерывно обновляться.
Следуя изложенным выше соображениям, мы должны были бы избегать зацепления в программе, то есть слишком тесного соединения модели и ее графического образа. В частности, модели не следует знать, как она отображается на экране (например, как представляются значения: численно или графически). Как может модель без тесной связи с методами отображения потребовать от них обновления экрана?
Один из способов избежать слишком сильной взаимозависимости между связанными компонентами — использовать администратор зависимостей. Он является стандартной частью run-time библиотек в Smalltalk и Objective-C, но может быть легко сконструирован и для других языков (например, C++). Основная идея состоит в том, что администратор зависимостей действует как посредник, обслуживая список объектов и других компонент, от них зависящих. Модели требуется знать только об администраторе зависимостей. Объекты-отображения «регистрируют» себя с помощью администратора зависимостей, указывая при этом, что они зависят от объекта-модели. Впоследствии объект-модель при своем изменении посылает единственное сообщение администратору зависимостей. Тем самым последний узнает, что модель изменилась и все зависимые от нее компоненты должны быть оповещены об этом. Зависимые компоненты получают сообщения от администратора зависимостей, которые извещают, что модель изменилась и должны быть предприняты надлежащие действия.
Такая система обслуживания зависимостей помогает лучше изолировать компоненты друг от друга, что уменьшает количество связей внутри программы. Однако в отличие от схемы, описанной в подразделе 17.1.6, она работает, только если зависимые компоненты знают, что кто-то ожидает их изменения. Она не будет работать, если, как в случае примера объекта Reactor, желательно минимизировать вмешательство в исходный код модели.
Упражнения
1.Разработайте средство, обнаруживающее нарушения закона Деметера, в программах, написанных на вашем любимом объектно-ориентированном языке.
2.Сильная форма закона Деметера запрещает доступ к экземплярам класса потомка. Опишите преимущества и недостатки этого ограничения. Рассмотрите такие моменты, как зацепление между классами и понятность кода программы.
3.Не кажется ли вам, что сильная форма закона Деметера должна ограничивать доступ также и к глобальным переменным? Обоснуйте свое мнение. Обдумывая ответ, вы можете обратиться к статье Вульфа и Шоу [Wulf 1973].
4.Какие еще можно предложить конкретные правила, аналогичные закону Деметера, такие, что:
oих выполнение обычно приводит к системам с меньшей взаимозависимостью;
o ситуации, когда правила должны нарушаться, встречаются редко.
Закон Деметера посвящен зацеплению между различными объектами. Можно ли предложить правила, которые стимулировали бы большую связность внутри объекта?