如何理解装饰者(Decorator)设计模式

装饰者模式是对原有类进行多次附加,比单纯的继承更加灵活的组和。
本例参照网上黄焖鸡点加小菜的实例来讲解。
生活中不同的人喜欢加不一样的小菜,如不用装饰者模式,肯定要加一堆的if else。长期下去不利于代码的维护。

菜品抽象类

abstract class Food {
	public $desc = "菜品";
	public $price = 0;

	public function getPrice() {
		return $this -> desc . ":" . $this -> price;
	}

	public function getDesc() {
		return $this -> desc;
	}

	abstract public function cost();
}

装饰者的抽象类

abstract class FoodDecorator extends Food {
	public $obj;

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

菜品类

class Rice extends Food {
	public $desc = "黄焖鸡";
	public $price = 20;

	public function cost() {
		return $this -> price;
	}
}

使用装饰者加鸡蛋类

class Egg extends FoodDecorator {
	public $desc = "鸡蛋";
	public $price = 2;

	public function cost() {
		return $this -> obj -> cost() + $this -> price;
	}

	public function getDesc() {
		return $this -> obj -> getDesc() . " + " . $this -> desc;
	}

	public function getPrice() {
		return $this -> obj -> getPrice() . " + " . $this -> desc . ":" . $this -> price;
	}
}

使用装饰者加蔬菜类

class Veg extends FoodDecorator {
	public $desc = "蔬菜";
	public $price = 1.5;

	public function cost() {
		return $this -> obj -> cost() + $this -> price;
	}

	public function getDesc() {
		return $this -> obj -> getDesc() . " + " . $this -> desc;
	}

	public function getPrice() {
		return $this -> obj -> getPrice() . " + " . $this -> desc . ":" . $this -> price;
	}
}

点餐系统实现
用户点一份黄焖鸡加鸡蛋和蔬菜

echo "-------------------欢迎使用--------------\n";
$rice = new Rice();
$egg = new Egg($rice);
$veg = new Veg($egg);
echo "菜品:";
print_r($veg -> getDesc());
echo "\n";
echo "单价:";
print_r($veg -> getPrice());
echo "\n";
echo "总计:";
print_r($veg -> cost());
echo "\n";
echo "------------------------------------------\n";

output:

-------------------欢迎使用--------------
菜品:黄焖鸡 + 鸡蛋 + 蔬菜
单价:黄焖鸡:20 + 鸡蛋:2 + 蔬菜:1.5
总计:23.5
------------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章