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

Презентация:



Advertisements
Похожие презентации
OOП Инна Исаева. Подпрограмма – это большая программа, разделённая на меньшие части. В программе одна из подпрограмм является главной. Её задача состоит.
Advertisements

1 Диаграммы реализации (implementation diagrams).
Шаблоны проектирования Design Pattern Наблюдатель (Observer) или Слушатель (Listener) по книге Эрик и Элизабет Фримен Паттерны проектирования.
Объекто-ориентированное проектирование Паттерны проектирования. 28 февраля 2008 г. 4 курс Технологии программирования.
1 ИССЛЕДОВАНИЕ ВОЗМОЖНОСТЕЙ COM- ТЕХНОЛОГИИ ДЛЯ ПОСТРОЕНИЯ РАСПРЕДЕЛЕННЫХ ПРОГРАММНЫХ ПРОДУКТОВ Component Object Model Министерство образования и науки.
Delphi. 11 класс.. Познакомиться с понятиями : Инкапсуляция Интерфейс объекта Классы, экземпляр класса Наследование, иерархия полиморфизм.
Что такое паттерны (шаблоны) проектирования? Эффективные способы решения характерных задач проектирования Обобщенное описание решения задачи, которое.
Алгоритмический подход – главное алгоритм решения задачи ( в основном, используется для вычислительных задач ); Структурное программирование – декомпозиция,
Методология объектно- ориентированного программирования.
Технические возможности. Наши цели Максимальная гибкость Максимальная скорость считывания и обработки данных Стабильность работы Максимальная простота.
1 Java 6. ИНТЕРФЕЙСЫ И ВНУТРЕННИЕ КЛАССЫ. 2 Интерфейсы Не являются классами Ни один из объявленных методов не может быть реализован внутри интерфейса.
Программная иженерия Андрей Дмитриев ©
Кафедра ОСУ, Java 2007 Слайд 1 Методология ООП В формулировке цели участвуют предметы (объекты) и понятия реального мира, имеющие отношение.
Шаблоны проектирования Design Pattern Фабрика (Factory) по книге Эрик и Элизабет Фримен Паттерны проектирования.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Java, каф. ОСУ АВТФ1 Методология ООП В формулировке цели выполнения некоторого проекта (например, разработка ИС) участвуют предметы (объекты)
1 © Luxoft Training 2012 Введение в ООП Модуль #2.
©Павловская Т.А. (СПбГУ ИТМО) Курс «С#. Программирование на языке высокого уровня» Павловская Т.А.
В. И. Дихтяр ИНФОРМАТИКА Российский университет дружбы народов Институт гостиничного бизнеса и туризма Раздел 3Моделирование объектов и процессов и его.
Полиморфизм. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Транксрипт:

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

2 Система заказов и реальный ассортимент Сеть кофеен Starbuss Beverage getDescription() cost() // другие методы … description HouseBlend cost() DarckRoast cost() Decaf cost() Espresso cost() Классы заказов для вычисления стоимости

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

4 Версия cost() суперкласса вычисляет стоимость всех компонентов, а переопределенная версия добавляет стоимость конкретного напитка Beverage getDescription() cost() hasMilk() setMilk() hasSoy() setSoy() … description milk soy mocha whip HouseBlend cost() Decaf cost() Espresso cost() DarckRoast cost() Глупо! Зачем нужны все эти классы? Разве для отслеживания дополнений нельзя использовать переменные экземпляров в суперклассе и наследование?

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

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

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

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

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

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

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

12 Диаграма классов Компонент может использоваться как сам по себе, так и «завернутым» в декоратор Декоратор содержит компонент Component metodA() metodB() // другие методы ConcreteComponent metodA() metodB() // другие методы ConcreteDecoratorA metodA() metodB() newBehavior() // другие методы Decorator metodA() metodB() // другие методы Component wrappedObj Object newState metodA() metodB() // другие методы ConcreteDecoratorB Декоратор реализует тот же интерфейс (расширяет класс), что и декорируемый компонент Объект, поведение которого надо расширить динамически, является субклассом Component Декораторы могут расширять состояние компонента Декораторы могут добавлять новые методы ( до или после вызова существующего метода)

13 Иерархия напитков Beverage getDescription() cost() // другие методы … description HouseBlend cost() DarckRoast cost() Decaf cost() Espresso cost() CondimentDecorator getDescription() Beverage beverage Milk cost() getDescription() Mocha cost() getDescription() Soy cost() getDescription() Whip cost() getDescription() Наследование ДЛЯ согласовани типов, а НЕ ДЛЯ обеспечения поведения Поведение добавляется посредством композиции Вместо абстрактного класса (Beverage) можно пользоваться интерфейсом реализация Starbuzz

14 Ввод/вывод в языке Java Типичный набор объектов, использующих декораторы для расширения функциональности чтения данных из файла: BufferedInputStream и LineNumberlnputStream расширяют FilterInputStream - абстрактный класс декоратора. Конкретный декоратор LineNumberlnputStream добавляет возможность подсчета строк в процессе чтения данных. Конкретный декоратор BufferedlnputStream буферизует ввод для повышения производительности и дополняет интерфейс новым методом readLine() для построчного чтения символьных данных Текстовый файл FilelnputStream декорируемый компонент, библиотека ввода/вывода Java предоставляет базовые компоненты FilelnputStream, StringBufferlnputStream, ByteArrayInputStream, предназначенные для чтения байтов данных.

15 Декорирование классов java.io Абстрактный компонент Абстрактный декоратор Конкретные декораторы Конкретные компоненты InputStream FileInputStream PushbackInputStreamDataInputStream BufferedInputStream StringBuferedInputStream ByteArrayInputStream FilterInputStream LineNumberInputStream Выходные потоки используют аналогичную архитектуру. Потоки Reader/Writer (для символьных данных) достаточно близко отражают архитектуру потоковых классов. собственная реализация декоратора ввода/вывода

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

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

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