Инструменты пользователя

Инструменты сайта


php:shablony_proektirovanija:structural_patterns:decorator

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
php:shablony_proektirovanija:structural_patterns:decorator [2023/08/17 13:30]
werwolf создано
php:shablony_proektirovanija:structural_patterns:decorator [2023/08/17 13:58] (текущий)
werwolf
Строка 1: Строка 1:
-## Декоратор (Decorator)+===== Декоратор (Decorator) ​=====
  
-[▶ code](http://​webmastermsk.ru:​30000/​serg/​patterns-php/​-/​blob/​main/​structural/​Decorator.php)+[[http://​webmastermsk.ru:​30000/​serg/​patterns-php/​-/​blob/​main/​structural/​Decorator.php|▶ code]]
  
-Шаблон декоратора позволяет динамически изменять поведение объекта во время выполнения,​ заключая его в объект класса +Шаблон декоратора позволяет динамически изменять поведение объекта во время выполнения,​ заключая его в объект класса 
-декоратора.+декоратора.
  
-Возможность динамически добавлять новые обязанности,​ не прибегая к порождению подклассов,​ облегчает понимание основных+Возможность динамически добавлять новые обязанности,​ не прибегая к порождению подклассов,​ облегчает понимание основных\\ 
 обязанностей объектов и не запутывает основную бизнес-логику информационных систем. обязанностей объектов и не запутывает основную бизнес-логику информационных систем.
  
-Можно добавлять и удалять обязанности во время выполнения программы,​ в то время как при использовании наследования надо+Можно добавлять и удалять обязанности во время выполнения программы,​ в то время как при использовании наследования надо\\ 
 было бы создавать новый класс для каждой дополнительной обязанности. было бы создавать новый класс для каждой дополнительной обязанности.
  
-Данный шаблон позволяет не создавать классов,​ перегруженных методами. Новые обязанности можно добавлять только по мере+Данный шаблон позволяет не создавать классов,​ перегруженных методами. Новые обязанности можно добавлять только по мере\\ 
 необходимости,​ не перегружая программное обеспечение лишними классами. необходимости,​ не перегружая программное обеспечение лишними классами.
  
 **Использование:​** **Использование:​**
  
-Когда вам нужно добавлять обязанности объектам на лету, незаметно для кода, который их использует. +  * Когда вам нужно добавлять обязанности объектам на лету, незаметно для кода, который их использует. 
-    ​Объекты помещают в обёртки,​ имеющие дополнительные поведения. Обёртки и сами объекты имеют одинаковый интерфейс,​ +    ​Объекты помещают в обёртки,​ имеющие дополнительные поведения. Обёртки и сами объекты имеют одинаковый интерфейс,​\\  
-      поэтому клиентам без разницы,​ с чем работать – с обычным объектом данных или с обёрнутым. +поэтому клиентам без разницы,​ с чем работать – с обычным объектом данных или с обёрнутым. 
-Когда нельзя расширить обязанности объекта с помощью наследования. +  ​* ​Когда нельзя расширить обязанности объекта с помощью наследования. 
-    ​Во многих языках программирования есть ключевое слово final, которое может заблокировать наследование класса. +    ​Во многих языках программирования есть ключевое слово final, которое может заблокировать наследование класса.\\  
-      Расширить такие классы можно только с помощью Декоратора.+Расширить такие классы можно только с помощью Декоратора.
  
 **Преимущества:​** **Преимущества:​**
  
-Большая гибкость,​ чем у наследования. +  * Большая гибкость,​ чем у наследования. 
-Позволяет добавлять обязанности на лету. +  ​* ​Позволяет добавлять обязанности на лету. 
-Можно добавлять несколько новых обязанностей сразу. +  ​* ​Можно добавлять несколько новых обязанностей сразу. 
-Позволяет иметь несколько мелких объектов вместо одного объекта на все случаи жизни.+  ​* ​Позволяет иметь несколько мелких объектов вместо одного объекта на все случаи жизни.
  
 **Недостатки:​** **Недостатки:​**
  
-Трудно конфигурировать многократно обёрнутые объекты. +  * Трудно конфигурировать многократно обёрнутые объекты. 
-Обилие крошечных классов.+  ​* ​Обилие крошечных классов.
  
-<​details>​ 
-<​summary><​strong>​Связи с другими паттернами</​strong></​summary>​ 
  
-Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём+**Связи с другими паттернами** 
 + 
 +Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём\\ 
 Декоратор поддерживает рекурсивную вложенность,​ чего не скажешь об Адаптере. Декоратор поддерживает рекурсивную вложенность,​ чего не скажешь об Адаптере.
  
-Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель+Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель\\ 
 предоставляет тот же интерфейс. предоставляет тот же интерфейс.
  
-Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного+Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного\\ 
 выполнения операции через серию связанных объектов. Но есть и несколько важных отличий. выполнения операции через серию связанных объектов. Но есть и несколько важных отличий.
  
-Обработчики в Цепочке обязанностей могут выполнять произвольные действия,​ независимые друг от друга, а также в любой +Обработчики в Цепочке обязанностей могут выполнять произвольные действия,​ независимые друг от друга, а также в любой\\  
-момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие,​+момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие,​\\ 
 не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов. не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов.
  
-Компоновщик и Декоратор имеют похожие структуры классов из-за того, что оба построены на рекурсивной вложенности. Она+Компоновщик и Декоратор имеют похожие структуры классов из-за того, что оба построены на рекурсивной вложенности. Она\\ 
 позволяет связать в одну структуру бесконечное количество объектов. позволяет связать в одну структуру бесконечное количество объектов.
  
-Декоратор оборачивает только один объект,​ а узел Компоновщика может иметь много детей. Декоратор добавляет вложенному+Декоратор оборачивает только один объект,​ а узел Компоновщика может иметь много детей. Декоратор добавляет вложенному\\ 
 объекту новую функциональность,​ а Компоновщик не добавляет ничего нового,​ но «суммирует» результаты всех своих детей. объекту новую функциональность,​ а Компоновщик не добавляет ничего нового,​ но «суммирует» результаты всех своих детей.
  
-Но они могут и сотрудничать:​ Компоновщик может использовать Декоратор,​ чтобы переопределить функции отдельных частей+Но они могут и сотрудничать:​ Компоновщик может использовать Декоратор,​ чтобы переопределить функции отдельных частей\\ 
 дерева компонентов. дерева компонентов.
  
-Архитектура,​ построенная на Компоновщиках и Декораторах,​ часто может быть улучшена за счёт внедрения Прототипа. Он+Архитектура,​ построенная на Компоновщиках и Декораторах,​ часто может быть улучшена за счёт внедрения Прототипа. Он\\ 
 позволяет клонировать сложные структуры объектов,​ а не собирать их заново. позволяет клонировать сложные структуры объектов,​ а не собирать их заново.
  
 Стратегия меняет поведение объекта «изнутри»,​ а Декоратор изменяет его «снаружи». Стратегия меняет поведение объекта «изнутри»,​ а Декоратор изменяет его «снаружи».
  
-Декоратор и Заместитель имеют схожие структуры,​ но разные назначения. Они похожи тем, что оба построены на принципе +Декоратор и Заместитель имеют схожие структуры,​ но разные назначения. Они похожи тем, что оба построены на принципе\\  
-композиции и делегируют работу другим объектам. Паттерны отличаются тем, что Заместитель сам управляет жизнью сервисного+композиции и делегируют работу другим объектам. Паттерны отличаются тем, что Заместитель сам управляет жизнью сервисного\\ 
 объекта,​ а обёртывание Декораторов контролируется клиентом. объекта,​ а обёртывание Декораторов контролируется клиентом.
  
-</details>+ 
 +<code php> 
 + 
 +<?php 
 + 
 +interface Worker 
 +
 +    public function countSalary():​ int; 
 +
 + 
 +abstract class WorkerDecorator implements Worker 
 +
 +    public Worker $worker; 
 + 
 +    public function __construct(Worker $worker) 
 +    { 
 +        $this->​worker = $worker; 
 +    } 
 +
 + 
 +class Developer implements Worker 
 +
 +    public function countSalary():​ int 
 +    { 
 +        return 20 * 3000; 
 +    } 
 +
 + 
 +class DeveloperOverTime extends WorkerDecorator 
 +
 +    public function countSalary():​ int 
 +    { 
 +        return $this->​worker->​countSalary() + $this->​worker->​countSalary() * 0.2; 
 +    } 
 +
 + 
 +$developer = new Developer();​ 
 +$developerOverTime = new DeveloperOverTime($developer);​ 
 + 
 +echo $developer->​countSalary();​ // 60000 
 +echo $developerOverTime->​countSalary();​ // 72000 
 + 
 +// ----------- 2 ----------- 
 + 
 +interface Coffee 
 +
 +    public function getCost();​ 
 + 
 +    public function getDescription();​ 
 +
 + 
 +class SimpleCoffee implements Coffee 
 +
 +    public function getCost() 
 +    { 
 +        return 10; 
 +    } 
 + 
 +    public function getDescription() 
 +    { 
 +        return '​Simple coffee';​ 
 +    } 
 +
 + 
 +class MilkCoffee implements Coffee 
 +
 +    protected $coffee; 
 + 
 +    public function __construct(Coffee $coffee) 
 +    { 
 +        $this->​coffee = $coffee; 
 +    } 
 + 
 +    public function getCost() 
 +    { 
 +        return $this->​coffee->​getCost() + 2; 
 +    } 
 + 
 +    public function getDescription() 
 +    { 
 +        return $this->​coffee->​getDescription() . ', milk';​ 
 +    } 
 +
 + 
 +class WhipCoffee implements Coffee 
 +
 +    protected $coffee; 
 + 
 +    public function __construct(Coffee $coffee) 
 +    { 
 +        $this->​coffee = $coffee; 
 +    } 
 + 
 +    public function getCost() 
 +    { 
 +        return $this->​coffee->​getCost() + 5; 
 +    } 
 + 
 +    public function getDescription() 
 +    { 
 +        return $this->​coffee->​getDescription() . ', whip';​ 
 +    } 
 +
 + 
 +$someCoffee = new SimpleCoffee();​ 
 +echo $someCoffee->​getCost();​ // 10 
 +echo $someCoffee->​getDescription();​ // Simple Coffee 
 + 
 +$someCoffee = new MilkCoffee($someCoffee);​ 
 +echo $someCoffee->​getCost();​ // 12 
 +echo $someCoffee->​getDescription();​ // Simple Coffee, milk 
 + 
 +$someCoffee = new WhipCoffee($someCoffee);​ 
 +echo $someCoffee->​getCost();​ // 17 
 +echo $someCoffee->​getDescription();​ // Simple Coffee, milk, whip 
 + 
 + 
 +// ----------- 3 ----------- 
 + 
 +interface Booking 
 +
 +    public function calculatePrice():​ int; 
 + 
 +    public function getDescription():​ string; 
 +
 + 
 +// Шаблон "​Декоратор"​ хранит ссылку на объект (компонент),​ определяет его интерфейс и переадресует на него рабочие запросы. 
 +abstract class BookingDecorator implements Booking 
 +
 +    public function __construct(protected Booking $booking) 
 +    { 
 +    } 
 +
 + 
 +// Системный компонент определяет интерфейс объекта,​ на который могут быть динамически возложены дополнительные обязанности 
 +class DoubleRoomBooking implements Booking 
 +
 +    public function calculatePrice():​ int 
 +    { 
 +        return 40; 
 +    } 
 + 
 +    public function getDescription():​ string 
 +    { 
 +        return '​double room';​ 
 +    } 
 +
 + 
 +// Конкретный компонент определяет объект,​ на который возлагаются дополнительные обязанности. 
 +class ExtraBed extends BookingDecorator 
 +
 +    private const PRICE = 30; 
 + 
 +    public function calculatePrice():​ int 
 +    { 
 +        return $this->​booking->​calculatePrice() + self::​PRICE;​ 
 +    } 
 + 
 +    public function getDescription():​ string 
 +    { 
 +        return $this->​booking->​getDescription() . ' with extra bed';​ 
 +    } 
 +
 + 
 +class WiFi extends BookingDecorator 
 +
 +    private const PRICE = 2; 
 + 
 +    public function calculatePrice():​ int 
 +    { 
 +        return $this->​booking->​calculatePrice() + self::​PRICE;​ 
 +    } 
 + 
 +    public function getDescription():​ string 
 +    { 
 +        return $this->​booking->​getDescription() . ' with wifi';​ 
 +    } 
 +
 + 
 +$booking = new DoubleRoomBooking();​ 
 + 
 +echo $booking->​calculatePrice();​ // 4 
 +echo $booking->​getDescription();​ // double room 
 + 
 +$booking2 = new DoubleRoomBooking();​ 
 +$booking2 = new WiFi($booking2);​ 
 + 
 +echo $booking2->​calculatePrice();​ // 42 
 +echo $booking2->​getDescription();​ // double room with wifi 
 + 
 +$booking3 = new DoubleRoomBooking();​ 
 +$booking3 = new WiFi($booking);​ 
 +$booking3 = new ExtraBed($booking);​ 
 + 
 +echo $booking3->​calculatePrice();​ // 72 
 +echo $booking3->​getDescription();​ // double room with wifi with extra bed 
 +</code>
  
php/shablony_proektirovanija/structural_patterns/decorator.1692268230.txt.gz · Последние изменения: 2023/08/17 13:30 — werwolf