當我們的一個對象可能代表一個單一的實體,或者一個組合的實體,但是仍然需要通過同樣的方式被使用時,這種情形則適合使用組合模式的設計。 ...
當我們的一個對象可能代表一個單一的實體,或者一個組合的實體,但是仍然需要通過同樣的方式被使用時,這種情形則適合使用組合模式的設計。
組合模式是一種結構型模式。
當看了書上的解釋之後,並不是很理解,遂去翻了翻《大化設計模式》,以下為原文截圖:
看完這本書上的解釋之後也不是很理解,但是能夠進行編碼了,以下為組合模式的代碼:
<?php /** * 組合模式抽象基類 */ abstract class CompanyBase{ //節點名稱 protected $name; public function __construct($name){ $this->name = $name; } public function getName(){ return $this->name; } //增加節點 abstract function add(CompanyBase $c); //刪除節點 abstract function remove(CompanyBase $c); //輸出節點信息 abstract function show($deep); //節點職責 abstract function work($deep); } /** * 公司類 */ class Company extends CompanyBase{ protected $item = []; public function add(CompanyBase $c){ $nodeName = $c->getName(); if(!isset( $this->item[$nodeName] )){ $this->item[$nodeName] = $c; }else{ throw new Exception("該節點已存在,節點名稱:".$nodeName); } } public function remove(CompanyBase $c){ $nodeName = $c->getName(); if(isset( $this->item[$nodeName] )){ unset($this->item[$nodeName]); }else{ throw new Exception("該節點不存在,節點名稱:".$nodeName); } } public function show($deep = 0){ echo str_repeat("-",$deep).$this->name; echo "<br>"; foreach($this->item as $value){ $value->show($deep+4); } } public function work($deep = 0){ foreach($this->item as $value){ echo str_repeat(" ",$deep)."[{$this->name}]<br>"; $value->work($deep+2); } } } /** * 人力資源部門 */ class HumanResources extends CompanyBase{ public function add(CompanyBase $c){ throw new Exception("該節點下不能增加節點"); } public function remove(CompanyBase $c){ throw new Exception("該節點下無子節點"); } public function show($deep = 0){ echo str_repeat("-",$deep).$this->name; echo "<br>"; } public function work($deep = 0){ echo str_repeat(" ",$deep)."人力資源部門的工作是為公司招聘人才"; echo "<br>"; } } /** * 商務部門 */ class Commerce extends CompanyBase{ public function add(CompanyBase $c){ throw new Exception("該節點下不能增加節點"); } public function remove(CompanyBase $c){ throw new Exception("該節點下無子節點"); } public function show($deep = 0){ echo str_repeat("-",$deep).$this->name; echo "<br>"; } public function work($deep = 0){ echo str_repeat(" ",$deep)."商務部門的工作是為公司賺取利潤"; echo "<br>"; } }
設計好類之後,就可以使用它了:
$c = new Company("北京某科技公司"); $h = new HumanResources("人力資源部門"); $com = new Commerce("商務部門"); $c->add($h); $c->add($com); //天津分公司 //為了偷懶,分公司的部門直接copy母公司的 $c1 = new Company("天津分公司"); $c1->add($h); $c1->add($com); $c->add($c1); //武漢分公司 $c2 = new Company("武漢分公司"); $c2->add($h); $c2->add($com); $c->add($c2); //使用公司功能 $c->show(); $c->work();
輸出:
總結以下組合模式的特點:
- 必須存在不可分割基本元素;
- 組合後的物體任然可以被組合。