# 装饰模式-PHP

# 咖啡

咖啡添加配料。

<?php

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';
    }
}

class VanillaCoffee implements Coffee {
    protected $coffee;

    public function __construct(Coffee $coffee) {
        $this->coffee = $coffee;
    }

    public function getCost() {
        return $this->coffee->getCost() + 3;
    }

    public function getDescription() {
        return $this->coffee->getDescription() . ', vanilla';
    }
}

// client
$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

$someCoffee = new VanillaCoffee($someCoffee);
echo $someCoffee->getCost(); // 20
echo $someCoffee->getDescription(); // Simple Coffee, milk, whip, vanilla

# 标准例子

装饰模式的标准例子。

<?php

abstract class Component {
    abstract public function Operation();
}

class ConcreteComponent extends Component {
    public function Operation() {
        echo "具体对象的操作\n";
    }
}

abstract class Decorator extends Component {
    protected $component;

    // 设置component
    public function SetComponent($component) {
        $this->component = $component;
    }

    // 重写Operation(),实际执行的是component的Operation方法
    public function Operation() {
        if ($this->component != null) {
            $this->component->Operation();
        }
    }
}

// 装饰类A
class ConcreteDecoratorA extends Decorator {
    // 本类的独有功能,以区别于ConcreteDecoratorB
    private $addedState;

    public function Operation() {
        // 首先运行原Component的Operation(),再执行本类的功能
        // 如addedState,相当于对原Component进行了装饰
        parent::Operation();
        $this->addedState = "ConcreteDecoratorA Status";
        echo $this->addedState."\n";
        echo "具体装饰对象A的操作\n";
    }
}

// 装饰类B
class ConcreteDecoratorB extends Decorator {
    public function Operation() {
        // 首先运行原Component的Operation(),再执行本类的功能,
        // 如addedBehavior,相当于对原Component进行了装饰
        parent::Operation();
        $this->addedBehavior();
        echo "具体装饰对象B的操作\n";
    }

    // 本类的独有功能,以区别于ConcreteDecoratorA
    private function addedBehavior() {
        echo "ConcreteDecoratorB Status\n";
    }
}

// client
$c = new ConcreteComponent();
$d1 = new ConcreteDecoratorA();
$d2 = new ConcreteDecoratorB();

$d1->SetComponent($c);
$d2->SetComponent($d1);
$d2->Operation();

# 穿衣打扮

搭配各种服装。

<?php

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function show() {
        echo "打扮".$this->name."\n";
    }
}

class Finery {
    protected $person;

    public function decorate($person) {
        $this->person = $person;
    }

    public function show() {
        if ($this->person != null) {
            $this->person->show();
        }
    }
}

class TShirts extends Finery {
    public function show() {
        echo "大T恤\n";
        parent::show();
    }
}

class BigTrouser extends Finery {
    public function show() {
        echo "跨裤\n";
        parent::show();
    }
}

class Sneakers extends Finery {
    public function show() {
        echo "破球鞋\n";
        parent::show();
    }
}

class Suit extends Finery {
    public function show() {
        echo "西装\n";
        parent::show();
    }
}

class Tie extends Finery {
    public function show() {
        echo "领带\n";
        parent::show();
    }
}

class LeatherShoes extends Finery {
    public function show() {
        echo "皮鞋\n";
        parent::show();
    }
}

// client
$person = new Person("alex");

$sneakers = new Sneakers();
$bigTrouser = new BigTrouser();
$tShirts = new TShirts();

$sneakers->decorate($person);
$bigTrouser->decorate($sneakers);
$tShirts->decorate($bigTrouser);
$tShirts->show();
最近更新时间: 2023/3/21 19:40:56