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

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


php:shablony_proektirovanija:structural_patterns:decorator

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
php:shablony_proektirovanija:structural_patterns:decorator [2023/08/17 13:56]
werwolf
php:shablony_proektirovanija:structural_patterns:decorator [2023/08/17 13:58] (текущий)
werwolf
Строка 37: Строка 37:
  
  
-<​code><​summary><​strong>​Связи с другими паттернами</​strong></​summary>​ +**Связи с другими паттернами**
-<​br>​ +
-Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём +
-Декоратор поддерживает рекурсивную вложенность,​ чего не скажешь об Адаптере.<​br>​ +
-<​br>​ +
-Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель +
-предоставляет тот же интерфейс.<​br>​ +
-<​br>​ +
-Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного +
-выполнения операции через серию связанных объектов. Но есть и несколько важных отличий.<​br>​ +
-<​br>​ +
-Обработчики в Цепочке обязанностей могут выполнять произвольные действия,​ независимые друг от друга, а также в любой +
-момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие,​ +
-не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов.<​br>​ +
-<​br>​ +
-Компоновщик и Декоратор имеют похожие структуры классов из-за того, что оба построены на рекурсивной вложенности. Она +
-позволяет связать в одну структуру бесконечное количество объектов.<​br>​ +
-<​br>​ +
-Декоратор оборачивает только один объект,​ а узел Компоновщика может иметь много детей. Декоратор добавляет вложенному +
-объекту новую функциональность,​ а Компоновщик не добавляет ничего нового,​ но «суммирует» результаты всех своих детей.<​br>​ +
-<​br>​ +
-Но они могут и сотрудничать:​ Компоновщик может использовать Декоратор,​ чтобы переопределить функции отдельных частей +
-дерева компонентов.<​br>​ +
-<​br>​ +
-Архитектура,​ построенная на Компоновщиках и Декораторах,​ часто может быть улучшена за счёт внедрения Прототипа. Он +
-позволяет клонировать сложные структуры объектов,​ а не собирать их заново.<​br>​ +
-<​br>​ +
-Стратегия меняет поведение объекта «изнутри»,​ а Декоратор изменяет его «снаружи».<​br>​ +
-<​br>​ +
-Декоратор и Заместитель имеют схожие структуры,​ но разные назначения. Они похожи тем, что оба построены на принципе +
-композиции и делегируют работу другим объектам. Паттерны отличаются тем, что Заместитель сам управляет жизнью сервисного +
-объекта,​ а обёртывание Декораторов контролируется клиентом.<​br></​code>​+
  
 +Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём\\ ​
 +Декоратор поддерживает рекурсивную вложенность,​ чего не скажешь об Адаптере.
 +
 +Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель\\ ​
 +предоставляет тот же интерфейс.
 +
 +Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного\\ ​
 +выполнения операции через серию связанных объектов. Но есть и несколько важных отличий.
 +
 +Обработчики в Цепочке обязанностей могут выполнять произвольные действия,​ независимые друг от друга, а также в любой\\ ​
 +момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие,​\\ ​
 +не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов.
 +
 +Компоновщик и Декоратор имеют похожие структуры классов из-за того, что оба построены на рекурсивной вложенности. Она\\ ​
 +позволяет связать в одну структуру бесконечное количество объектов.
 +
 +Декоратор оборачивает только один объект,​ а узел Компоновщика может иметь много детей. Декоратор добавляет вложенному\\ ​
 +объекту новую функциональность,​ а Компоновщик не добавляет ничего нового,​ но «суммирует» результаты всех своих детей.
 +
 +Но они могут и сотрудничать:​ Компоновщик может использовать Декоратор,​ чтобы переопределить функции отдельных частей\\ ​
 +дерева компонентов.
 +
 +Архитектура,​ построенная на Компоновщиках и Декораторах,​ часто может быть улучшена за счёт внедрения Прототипа. Он\\ ​
 +позволяет клонировать сложные структуры объектов,​ а не собирать их заново.
 +
 +Стратегия меняет поведение объекта «изнутри»,​ а Декоратор изменяет его «снаружи».
 +
 +Декоратор и Заместитель имеют схожие структуры,​ но разные назначения. Они похожи тем, что оба построены на принципе\\ ​
 +композиции и делегируют работу другим объектам. Паттерны отличаются тем, что Заместитель сам управляет жизнью сервисного\\ ​
 +объекта,​ а обёртывание Декораторов контролируется клиентом.
 +
 +
 +<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.1692269771.txt.gz · Последние изменения: 2023/08/17 13:56 — werwolf