首頁  >  文章  >  後端開發  >  樹狀的組合模式(composite pattern)

樹狀的組合模式(composite pattern)

巴扎黑
巴扎黑原創
2016-11-12 14:08:451487瀏覽

一個公司是由每個工作的成員組成,每一個成員有不同的屬性(名字,職位,薪水),根據不同的等級,構成一個樹形的結構。總經理是這棵樹的根節點,因為他沒有上級,部門經理是樹枝節點,因為他既有上級也有下級,小嘍囉是葉節點,因為他是最底層的苦逼,沒有下級。現用組合模式將這個樹展示出來,類別圖:

樹狀的組合模式(composite pattern)

代碼如下:

<?php
abstract class Corp {
private $name = &#39;&#39;;
private $position = &#39;&#39;;
private $salary = 0;
public function __construct( $name, $position, $salary ) {
$this->name = $name;
$this->position = $position;
$this->salary = $salary;
}
public function getInfo() {
$return = "姓名:".$this->name."\t";
$return .= "职位:".$this->position."\t";
$return .= "薪水:".$this->salary."\n";
return $return;
}
}
class Leaf extends Corp{
}
class Branch extends Corp{
private $subordinateList = array();
public function addSubordinate(Corp $corp){
array_push($this->subordinateList, $corp);
}
public function getSubordinateList(){
return $this->subordinateList;
}
}
$root = new Branch(&#39;马总&#39;,&#39;总经理&#39;,100000);
$branch1 = new Branch(&#39;罗总&#39;,&#39;研发部门经理&#39;,20000);
$branch2 = new Branch(&#39;高总&#39;,&#39;销售部门经理&#39;,80000);
$leaf1 = new Leaf(&#39;张三&#39;,&#39;开发人员&#39;,7000);
$leaf2 = new Leaf(&#39;李四&#39;,&#39;开发人员&#39;,8000);
$leaf3 = new Leaf(&#39;二蛋&#39;,&#39;销售人员&#39;,10000);
$leaf4 = new Leaf(&#39;狗子&#39;,&#39;销售人员&#39;,15000);
$root->addSubordinate($branch1);
$branch1->addSubordinate($leaf1);
$branch1->addSubordinate($leaf2);
$root->addSubordinate($branch2);
$branch2->addSubordinate($leaf3);
$branch2->addSubordinate($leaf4);
function getTreeInfo($branch){
echo $branch->getInfo();
$subordinateList = $branch->getSubordinateList();
foreach ($subordinateList as $value) {
if($value instanceof Branch){
getTreeInfo($value);
}else{
echo $value->getInfo();
}
}
}
getTreeInfo($root);
?>

運作結果:

姓名:馬總 職位:總經理 薪水:100000經理 薪水:20000

姓名:張三 職位:開發人員 薪水:7000

姓名:李四 職位:開發人員 薪水:8000

姓名:高總 職位:銷售部門經理 薪水:800000%職位:銷售人員 薪水:10000

姓名:狗子 職位:銷售人員 薪水:15000

[Finished in 0.1s]

組合模式的定義

組合模式也叫合成模式,也叫部分合成模式主要是用來描述部分與整體的關係。其定義為:將物件組合成樹狀結構以表示」部分-整體「的層次結構,使得使用者對單一物件和組合物件的使用具有一致性。組合模式主要由三個角色構成

1、Component抽象構件角色

定義參加組合物件的共有方法和屬性,可以定義一些預設的行為或屬性,例如範例中的Corp類別。

2、Leaf葉子構件

3、Composite樹枝構件

組合樹枝節點和葉子節點形成一個樹形結構

組合模式的優點

1、高層模組調用簡單

組合模式的優點

1、高層模組調用簡單

組合模式的優點

1、高層模組調用簡單

組合模式的優點

1、高層模組調用簡單

所有節點都是Component,局部和整體對呼叫者來說沒有任何區別,也就是說,高層模組不必關心自己處理的是單一物件還是整個組合結構,簡化了高層模組的程式碼。

2、節點自己增加

只要找到它的父節點就成,非常容易擴展,符合開閉原則。

組合模式的缺點組合模式有一個非常明顯的缺點,看到在場景類別中的定義,提到樹葉和樹枝使用時的定義了嗎?直接使用了實作類別!這在面向介面程式設計上是很不恰當的,與依賴代表團原則衝突,限制了介面中的影響範圍。

組合模式的使用場景

1、維護和展示部分-整體關係的場景,如樹形選單、文件、資料夾管理。

2、從一個整體中的能夠獨立出總價模組或功能的場景。

 

組合模式的注意事項

只要是樹形結構,就要考慮使用組合模式,這個一定要記住,只要是要體現局部和整體的關係的時候,而且這種關係還可能比較深,就應該考慮一下組合模式。

組合模式的擴展

1、真實的組合模式(略過)

2、透明的組合模式樹狀的組合模式(composite pattern)

例子中是安全的組合模式,透明模式是把用來組合的方法放到抽象類別中(略過)

3、組合模式的遍歷

例子中實現了樹的從上級向下級遍歷,如果現隨便選中一個葉節點,如何向上級做遍歷?

 其實也很簡單,只要在新增節點時設定其父節點既可,代碼如下:

<?php
abstract class Corp {
private $name = &#39;&#39;;
private $position = &#39;&#39;;
private $salary = 0;
<strong>private $parent = null;</strong>
public function __construct( $name, $position, $salary ) {
$this->name = $name;
$this->position = $position;
$this->salary = $salary;
}
public function getInfo() {
$return = "姓名:".$this->name."\t";
$return .= "职位:".$this->position."\t";
$return .= "薪水:".$this->salary."\n";
return $return;
}
<strong>public function setParent($parent){
$this->parent = $parent;
}
public function getParent(){
return $this->parent;
}</strong>
}
class Leaf extends Corp{
}
class Branch extends Corp{
private $subordinateList = array();
public function addSubordinate(Corp $corp){
<strong>$corp->setParent($this);</strong>
array_push($this->subordinateList, $corp);
}
public function getSubordinateList(){
return $this->subordinateList;
}
}
$root = new Branch(&#39;马总&#39;,&#39;总经理&#39;,100000);
$branch1 = new Branch(&#39;罗总&#39;,&#39;研发部门经理&#39;,20000);
$branch2 = new Branch(&#39;高总&#39;,&#39;销售部门经理&#39;,80000);
$leaf1 = new Leaf(&#39;张三&#39;,&#39;开发人员&#39;,7000);
$leaf2 = new Leaf(&#39;李四&#39;,&#39;开发人员&#39;,8000);
$leaf3 = new Leaf(&#39;二蛋&#39;,&#39;销售人员&#39;,10000);
$leaf4 = new Leaf(&#39;狗子&#39;,&#39;销售人员&#39;,15000);
$root->addSubordinate($branch1);
$branch1->addSubordinate($leaf1);
$branch1->addSubordinate($leaf2);
$root->addSubordinate($branch2);
$branch2->addSubordinate($leaf3);
$branch2->addSubordinate($leaf4);
function getParentInfo($leaf){
echo $leaf->getInfo();
$parent = $leaf->getParent();
if($parent instanceof branch)
getParentInfo($parent);
}
getParentInfo($leaf4);
?>

運作結果:

姓名:狗子 職位:銷售人員 薪水:150000

職位:銷售部門經理 薪水:80000🎜🎜姓名:馬總 職位:總經理 薪水:100000🎜🎜[Finished in 0.2s]🎜🎜 代碼中黑體部分為與上一例的區別。 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn