如何理解裝飾者(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
------------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章