- •Предисловие 15
- •Предисловие
- •От авторов
- •Об авторах
- •Благодарности
- •Принятые в книге обозначения
- •Технические рекомендации
- •Дополнительные ресурсы
- •Глава 1. Введение
- •1.1. Понятие паттерна проектирования
- •Определение
- •Метафора
- •1.2. Формат описания паттернов проектирования
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •1.3. Каталог паттернов проектирования
- •Порождающие
- •Структурные
- •Поведенческие
- •1.4. Техники ООП
- •Фабрика - Продукт
- •Фасад - Подсистема
- •Диспетчеризация
- •Цепочка объектов
- •Издатель-Подписчик
- •1.5. Принципы организации каталога
- •Цель паттерна
- •Уровень паттерна
- •1.6. Рекомендации по изучению паттернов
- •1.7. Рекомендации по применению паттернов
- •Глава 2. Порождающие паттерны
- •Игра - Лабиринт
- •Паттерн Abstract Factory
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Builder
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Factory Method
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Prototype
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Singleton
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Глава 3. Структурные паттерны
- •Паттерн Adapter
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Adapter уровня классов
- •Adapter уровня объектов
- •Структура паттерна на языке C#
- •Adapter уровня классов
- •Adapter уровня объектов
- •Участники
- •Отношения между участниками
- •Отношения между классами (для адаптера уровня классов)
- •Отношения между классами (для адаптера уровня объектов)
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Adapter уровня классов
- •Adapter уровня объектов
- •Особенности применения паттерна Adapter
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Bridge
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Composite
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Decorator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Facade
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Flyweight
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Proxy
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Глава 4. Паттерны поведения
- •Паттерн Chain of Responsibility
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Command
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Interpreter
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Паттерн Iterator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Классическое представление
- •Представление Microsoft .NET
- •Структура паттерна на языке C#
- •Классическое представление
- •Представление Microsoft .NET
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Mediator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Memento
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Реализация
- •Паттерн Observer
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Модель вытягивания (Pull model)
- •Модель проталкивания (Push model)
- •Структура паттерна на языке C#
- •Модель вытягивания (Pull model)
- •Модель проталкивания (Push model)
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн State
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Паттерн Strategy
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Паттерн Template Method
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Результаты
- •Реализация
- •Паттерн Visitor
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Библиография
105
Паттерн Bridge
Название
Мост
Также известен как
Handle/Body (описатель/тело)
Классификация
По цели: структурный По применимости: к объектам
Частота использования
Средняя |
- 1 2 3 4 5 |
Назначение
Паттерн Bridge – позволяет отделить абстракцию от элементов ее реализации так, чтобы и абстракцию, и реализацию можно было изменять независимо друг от друга.
Введение
Абстракция – собирательное понятие дающее возможность просто и обобщенно представить сложную сущность, состоящую из множества частей. Любые абстракции формируются из конкретных понятий или других абстракций которые в свою очередь сформированы из конкретных понятий и т.д.
Конкретика – точное понятие, описывающее единичный (не требуемый разложения на более мелкие части) объект с ясно определенными признаками. Конкретика основана на реализации.
Конкретика и абстракция – философские понятия, поэтому они относительны и могут стать причиной разногласий при формировании уровней детализации как жизненных, так и виртуальных программных сущностей.
Рассмотрим такую абстракцию из объективной реальности как компьютер. Что такое компьютер? Компьютер – это собирательное понятие описывающее устройство, состоящее из конкретных частей – монитор, системный блок, клавиатура, манипулятор-мышь. Но кто-то возразит и предложит рассматривать системный блок как абстракцию, состоящую из конкретных частей таких как – корпус, блок питания, жесткий диск, материнская плата, процессор, ОЗУ, видеокарта, дисковод. Но, и тут можно возразить, и предложить рассмотреть более детально устройство процессора, и представить процессор как абстракцию, состоящую из триггеров и других элементов. Триггеры можно в свою очередь представить в форме абстракции и разложить на более мелкие элементы, например, транзисторы. Транзистор тоже можно представить, как абстракцию, состоящую из трех электродов (эмиттер, база, коллектор) и небольшого количества кремния. А что такое атом кремния? – это абстракция. Атом - собирательное понятие из нейтронов, протонов и электронов. А что такое нейтрон? … Так можно войти в паралич анализа и никогда не закончить декомпозицию каждой составляющей компьютера раскладывая на атомы все его составляющие. Когда же следует закончить декомпозицию и очередную абстракцию представить конкретикой? Тогда, когда мы согласны работать с устройством как с кибернетически черным ящиком (не понимая, как устройство функционирует) и готовы пренебречь гибкостью сопровождения данного устройства. Например, если вышло из строя устройство для чтения DVD дисков, то один человек просто заменит устройство на новое, а другой человек попытается его починить (обладая соответствующими знаниями).
Рассмотрим абстракцию из виртуальной реальности. Например, объект класса OpenFileDialog. Что такое OpenFileDialog? – это собирательное понятие, состоящее из набора элементов, представляющее собой диалоговое окно для выбора файла. Но, OpenFileDialog – конкретный класс, он спроектирован так, чтобы представлять собой точный единичный объект без возможности его расширения (sealed). Разработчики этого класса не рекомендуют воспринимать его как абстрактное понятие, и соответственно не рекомендуют детально разбираться в его устройстве. Рекомендуется им просто
106
пользоваться как черным ящиком, а настоящая абстракция расположена выше в графе наследования – в
классе FileDialog.
Граф наследования класса OpenFileDialog устроен так:
|
sealed class OpenFileDialog : FileDialog {…} |
||
в свою очередь: |
abstract |
class |
FileDialog : CommonDialog {…} |
в свою очередь: |
abstract |
class |
CommonDialog : Component {…} |
в свою очередь: |
class Component : MarshalByRefObject, IComponent, IDisposable {…} |
Формирование как конкретных понятий, так и абстрактных понятий, возможно производить двумя способами, через наследование классов и/или через композицию объектов.
Если некоторая абстракция подразумевает несколько реализаций (конкретик), то обычно применяют наследование. Например, абстракция FileDialog имеет две конкретные реализации, это классы OpenFileDialog и SaveFileDialog. Абстракция задает общий интерфейс взаимодействия с конкретными реализациями, тем самым формируя понятие общего типа. Конкретные классы могут поразному реализовать абстрактный интерфейс, главное, чтобы имена методов, составляющих общий интерфейс взаимодействия, соответствовали роду выполняемой ими деятельности.
Но, подход с наследованием разрушает гибкость и формирует хрупкость. Хрупкость базового класса
– фундаментальная проблема в ООП. Проблема хрупкого базового класса заключается в том, что изменения, внесенные в реализацию базового класса, могут негативно сказаться на работе производных классов. Наследование формирует сильнейшую форму связанности (coupling - мера зависимости) из всех возможных и разорвать эту связанность невозможно. Соответственно потеря гибкости означает – затруднение модификации, расширения и повторного использования как абстракции, так и реализации (конкретики). Использование паттерна Bridge позволяет решить описанные выше проблемы.
Предлагается воспользоваться паттерном Bridge для построения простейшей программы, которая рисует заданные геометрические фигуры линиями определенного стиля.
В качестве примера рассмотрим треугольник. Треугольник — это абстракция. Треугольник (в евклидовом пространстве) — это геометрическая фигура, образованная тремя отрезками, которые соединяют три не лежащие на одной прямой точки. Предлагается рассмотреть треугольники не в смысле геометрических типов (прямоугольные, равнобедренные и др.) а как выражения треугольных форм предметов из объективной реальности. Например, школьный треугольник, треугольник для бильярда и музыкальный треугольник.
Сам треугольник – это абстракция, а те части из которых он состоит – есть элементы реализации абстракции. Для школьного треугольника и треугольника для бильярда реализацией будут те деревянные стороны из которых он состоит, а для музыкального треугольника реализацией будет являться изогнутый металлический прут.
107
Для нарисованного на листе бумаги треугольника реализацией будет являться краска карандаша, нанесенная на лист бумаги.
Для нарисованного треугольника на Windows форме реализацией будет линия, вычерченная графическим устройством Graphics при помощи пера Pen.
Ниже представлена диаграмма классов на которой представлены две иерархии: классы геометрических форм Shape (абстракций) и линий LineStyle (реализаций).
См. Пример к главе: \007_Bridge\004_ Bridge WinForm (Shapes and Lines)
108
Структура паттерна на языке UML
См. Пример к главе: \007_Bridge\001_Bridge
Структура паттерна на языке C#
class Program
{
static void Main()
{
Abstraction abstraction;
abstraction = new RefinedAbstraction(new ConcreteImplementorA()); abstraction.Operation();
abstraction = new RefinedAbstraction(new ConcreteImplementorB()); abstraction.Operation();
}
}
abstract class Abstraction
{
protected Implementor implementor; |
|
|
|
|
|
|
public Abstraction(Implementor imp) |
|
|
|
|
|
|
{ |
|
|
abstract class Implementor |
|||
this.implementor = imp; |
|
|
||||
{ |
|
|
||||
} |
|
|
||||
|
|
public abstract void OperationImp(); |
||||
|
|
|
||||
public virtual void Operation() |
} |
|
|
|||
|
|
|
|
|
||
{ |
|
|
|
|
|
|
implementor.OperationImp(); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
class RefinedAbstraction : Abstraction |
|
|
|
|
|
|
class ConcreteImplementorA : Implementor |
class ConcreteImplementorB : Implementor |
|||||
{ |
||||||
{ |
|
|
{ |
|
||
public RefinedAbstraction(Implementor imp) |
|
|
|
|||
public override void OperationImp() |
public override void OperationImp() |
|||||
: base(imp) |
||||||
{ |
|
|
{ |
|
||
{ |
|
|
|
|||
Console.WriteLine("ImplementorA"); |
Console.WriteLine("ImplementorB"); |
|||||
} |
||||||
} |
|
|
} |
|
||
|
|
|
|
|||
public override void Operation() |
} |
|
|
} |
|
|
|
|
|
|
|
{
// ...
base.Operation(); // ...
}
}
См. Пример к главе: \007_Bridge\001_Bridge