Decorator.pptx
- Количество слайдов: 17
Decorator (Wrapper)
Назначение: Динамически расширяет функциональность объекта, добавляет ему новые обязанности. Гибкая альтернатива наследованию, когда подклассы создаются только чтоб просто расширить класс новыми возможностями.
Метафора
Используйте паттерн декоратор : Для динамического и прозрачного для клиентов добавления новых возможностей, «фич» объектам; Для реализации возможностей, которые нужны не всем объектам и не всегда, и потом можно было легко их исключить; Когда расширение путем порождения подклассов по каким-то причинам неудобно или невозможно. Иногда приходится реализовывать много независимых расширений, так что порождение подклассов для поддержки всех возможных комбинаций приведет к комбинаторному росту их числа ( «комбинаторный взрыв» ). В других случаях определение класса может быть скрыто или почему-либо еще недоступно, так что породить от него подкласс нельзя.
Зачем использовать декоратор? Пусть имеется некоторый объект — «кнопка» , принадлежащий классу объектов «Кнопка» , на который понадобилось возложить дополнительные обязанности: ◦ отображение рамки кнопки; ◦ надписи; ◦ иконки; Важно понимать, что все эти обязанности должны иметь возможность быть наложенными как одновременно, так и по отдельности.
Возможное решение: порождение классов (механизм наследования) (2^3 -1 = 7) различных классов, сочетающие в себе всевозможные комбинации обязанностей. Это классы: «Кнопка_С_Надписью» , «Кнопка_С_Рамкой» , «Кнопка_С_Иконкой» , «Кнопка_С_Надписью_И_Иконкой» , «Кнопка_С Рамкой_И_Иконкой» , «Кнопка_С_Надписью_И_Рамкой_И_Иконкой » .
Структура
Пример public interface Car { public int get. Price(); public String get. Description(); } Component (Car). Задает интерфейс для объектов, на которые могут быть динамически возложены дополнительные обязанности, ровно как задает его и для будущих декораторов.
public class Simple. Car implements Car { @Override public int get. Price() { return 100000; } @Override public String get. Description() { return "Simple auto"; } } Concrete. Component (Simple. Car) Определяет объект, на который возлагаются дополнительные обязанности, вешаются дополнительные возможности.
public abstract class Car. Decorator implements Car { protected final Car car; public Car. Decorator(Car car) { this. car = car; } @Override public int get. Price() { return car. get. Price(); } @Override public String get. Description() { return car. get. Description(); }} Decorator. Хранит ссылку на объект Component и наследует реализацию его интерфейса поумалчанию;
public class Conditioner extends Car. Decorator { public Conditioner(Car car) { super(car); } public int get. Price() { return car. get. Price() + 2000; } public String get. Description() { return car. get. Description() + " with conditioner"; } } Concrete. Decorator. Возлагает дополнительные обязанности на компонент
public class Leather. Interior extends Car. Decorator { public Leather. Interior(Car car) { super(car); } public int get. Price() { return car. get. Price() + 3000; } public String get. Description() { return car. get. Description() + " with leather interior"; } } Concrete. Decorator. Возлагает дополнительные обязанности на компонент.
public class Client { public static void main(String[] args) { Car car = new Simple. Car(); System. out. println("Price: " + car. get. Price() + ", Description: " + car. get. Description()); car = new Conditioner(car); System. out. println("Price: " + car. get. Price() + ", Description: " + car. get. Description()); } } car = new Leather. Interior(car); System. out. println("Price: " + car. get. Price() + ", Description: " + car. get. Description()); /** * Результат: * Price: 100000, Description: Simple auto * Price: 102000, Description: Simple auto with conditioner * Price: 105000, Description: Simple auto with conditioner with leather interior */
Результаты ü Большая гибкость, нежели у статического наследования. ü Позволяет избежать перегруженных функциями классов на верхних ü Множество мелких объектов.
Вопросы 1) Какова проблематика «декоратора» : Возложить дополнительные обязанности (прозрачные для клиентов) на отдельный объект, а не на класс в целом. Необходимо обеспечить взаимодействие несовместимых интерфейсов Как обрабатывать группу или композицию структур обьектов одновременно
2) Решение проблемы «декоратором» : Назначить обязанность расчета информации некоему классу (информационному эксперту), обладающему необходимой информацией. Динамически добавить объекту новые обязанности не прибегая при этом к порождению подклассов (наследованию). Поместить абстракцию и реализацию в отдельные иерархии классов.
3)Какие компоненты лежат в основе декоратора Компонент, конкретный компонент, декоратор, конкретные декораторы Компонент, конкретные декораторы, клиент Декоратор, конкретный компонет 4) Придумайте метафору к «декоратору»
Decorator.pptx