装饰器模式

类图

2024072116162888.png

最核心的点在于,装饰器也要实现 Component 接口。这样,当新增类时,就不需要修改客户端代码,满足开闭原则

代码

<?php
 
// 组件接口
interface Coffee
{
public function getPrice(): int;
}
 
class lightRoastCoffee implements Coffee
{
public function getPrice(): int
{
return 10;
}
}
 
class darkRoastCoffee implements Coffee
{
public function getPrice(): int
{
return 15;
}
}
 
// 装饰器
 
abstract class CoffeeDecorator implements Coffee
{
protected $coffee;
 
public function __construct(Coffee $coffee)
{
$this->coffee = $coffee;
}
 
public function getPrice(): int
{
return $this->coffee->getPrice();
}
}
 
class MilkDecorator extends CoffeeDecorator
{
public function getPrice(): int
{
return $this->coffee->getPrice() + 5;
}
}
 
class SugarDecorator extends CoffeeDecorator
{
public function getPrice(): int
{
return $this->coffee->getPrice() + 2;
}
}
 
// client
function getPrice(Coffee $coffee)
{
return $coffee->getPrice();
}
 
$lighRoastCoffee = new lightRoastCoffee();
$dakRoastCoffee = new darkRoastCoffee();
 
$milkDecorator = new MilkDecorator($lighRoastCoffee);
 
echo getPrice($milkDecorator);
 
$sugarDecorator = new SugarDecorator($dakRoastCoffee);
 
echo getPrice($sugarDecorator);