'

Шаблоны проектирования Design Pattern

Понравилась презентация – покажи это...





Слайд 0

Шаблоны проектирования Design Pattern Декоратор, оформитель (Decorator) по книге Эрик и Элизабет Фримен Паттерны проектирования


Слайд 1

2 Система заказов и реальный ассортимент Сеть кофеен Starbuss Классы заказов для вычисления стоимости


Слайд 2

3 Дополнения к кофе К кофе можно заказать различные дополнения (пенка, шоколад и т. д.), да еще украсить все сверху взбитыми сливками. Дополнения не бесплатны, поэтому они должны быть встроены в систему оформления заказов. Первая попытка..


Слайд 3

4 Глупо! Зачем нужны все эти классы? Разве для отслеживания дополнений нельзя использовать переменные экземпляров в суперклассе и наследование?


Слайд 4

5 Возможные изменения требований Изменение цены дополнений потребует модификации существующего кода. При появлении новых дополнений нам придется добавлять новые методы и изменять реализацию cost() в суперклассе. Для некоторых новых напитков (холодный чай?) дополнения могут оказаться неуместными, но субкласс Tea все равно будет наследовать hasWhip() и другие методы. А если клиент захочет двойную порцию шоколада? Потенциальные недостатки такого подхода видны, если подумать о возможных изменениях в будущем


Слайд 5

6 Наследование и композиция Наследование обладает большими возможностями, но оно не всегда приводит к самой гибкой или удобной в сопровождении архитектуре. Поведение, унаследованное посредством субклассирования, задается статически на стадии компиляции. Кроме того, оно должно наследоваться всеми субклассами. Расширение поведения объекта посредством композиции может осуществляться динамически. Сила композиции в том, что можно наделить объект новыми возможностями — даже теми, которые не были предусмотрены при проектировании суперкласса. При этом не придется изменять его код. Динамическая композиция объектов позволяет добавлять новую функциональность посредством написания нового кода (вместо изменения существующего).


Слайд 6

7 Принцип открытости/закрытости Один из важнейших принципов проектирования Цель заключается в том, чтобы классы можно было легко расширять новым поведением без изменения существующего кода. Что это дает? Архитектуры, устойчивые к изменениям и достаточно гибкие для поддержки новой функциональности в соответствии с изменившимися требованиями. Будьте осторожны с выбором расширяемых областей. ПОВСЕМЕСТНОЕ применение принципа открытости/закрытости неэффективно и расточительно, оно приводит к созданию сложного, малопонятного кода.


Слайд 7

8 Знакомство с паттерном декоратор Схема вычисления стоимости напитка с дополнениями посредством декорирования. Например, если клиент заказывает кофе темной обжарки (Dark Roast) с шоколадом (Mocha) и взбитыми сливками (Whip), то: берем объект DarkRoast; декорируем его объектом Mocha; декорируем его объектом Whip; вызываем метод cost() и пользуемся делегированием для прибавления стоимости дополнений. Но как «декорировать» объект, и как в этой схеме работает делегирование?


Слайд 8

9 Построение заказанного напитка Таким образом, объект DarkRoast «завернутый» в Mocha и Whip сохраняет признаки Beverage, и с ним можно делать все, что можно делать с DarkRoast, включая вызов метода cost().


Слайд 9

10 Вычисление общей стоимости напитка $1.29


Слайд 10

11 Определение паттерна Декоратор Что уже известно Декораторы имеют тот же супертип, что и декорируемые объекты. Объекты можно «завернуть» в один или несколько декораторов. Так как декоратор относится к тому же типу, что и декорируемый объект, можно передать декорированный объект вместо исходного. Декоратор добавляет свое поведение до и(или) после делегирования операций декорируемому объекту, выполняющему остальную работу. Объект может быть декорирован в любо момент времени, так что можно декорировать объекты динамически произвольным количеством декораторов. Паттерн Декоратор динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области расширения функциональности.


Слайд 11

12 Диаграма классов


Слайд 12

13 Иерархия напитков реализация Starbuzz


Слайд 13

14 Ввод/вывод в языке Java Типичный набор объектов, использующих декораторы для расширения функциональности чтения данных из файла: BufferedInputStream и LineNumberlnputStream расширяют FilterInputStream - абстрактный класс декоратора.


Слайд 14

15 Декорирование классов java.io Выходные потоки используют аналогичную архитектуру. Потоки Reader/Writer (для символьных данных) достаточно близко отражают архитектуру потоковых классов. собственная реализация декоратора ввода/вывода


Слайд 15

16 Ограничения на использование Декоратор – отличный паттерн для создания гибких архитектур и соблюдения принципа открытости/закрытости. Одно из главных достоинств заключается в том, что декораторы обычно вводятся в архитектуру прозрачно, а клиенту даже не нужно знать, что он имеет дело с декоратором. Ограничения Добавляет в архитектуру много мелких классов, и разобраться в ней становится весьма непросто. Если код зависит от конкретных типов, а вы применяете обобщенные декораторы, дело добром не кончится. Введение декораторов усложняет код создания экземпляра компонента. Если в архитектуре участвуют декораторы, необходимо не только создать компонент, но и «завернуть» его в сколько-то декораторов.


Слайд 16

17 Резюме Концепции ООП Абстракция Инкапсуляция Полиморфизм Наследование Стратегия определяет семейство алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. Он позволяет модифицировать алгоритмы независимо от их использования на стороне клиента. Наблюдатель определяет отношение «один-ко-многим» таким образом, что при изменений состояния одного объекта происходит автоматическое оповещение и обновление всех зависимых объектов. Принципы Инкапсулируйте, то что изменяется Отдавайте предпочтение композиции перед наследованием Программируйте на уровне интерфейсов, а не реализации Стремитесь к слабой связаности взаимодействующих объектов Классы должны быть открыты для расширения, но закрыты для изменения Паттерн Декоратор динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области расширения функциональности.


Слайд 17

18 Ключевые моменты Наследование — одна из форм расширения, но оно не всегда обеспечивает гибкость архитектуры. Следует предусмотреть возможность расширения поведения без изменения существующего кода. Композиция и делегирование часто используются для динамического добавления нового поведения. Паттерн Декоратор предоставляет альтернативу субклассированию в области расширения поведения. Типы декораторов соответствуют типам декорируемых компонентов (соответствие достигается посредством наследования или реализации интерфейса). Декораторы изменяют поведение компонентов, добавляя новую функциональность до и (или) после (или даже вместо) вызовов методов компонентов. Компонент может декорироваться любым количеством декораторов. Декораторы обычно прозрачны для клиентов компонента (если клиентский код не зависит от конкретного типа компонента).


×

HTML:





Ссылка: