<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                組合(Composite)模式:有時又叫作部分-整體模式。將對象組合成樹狀層次結構,使用戶對單個對象和組合對象具有一致的訪問性。 **主要優點有:** 1. 組合模式使得客戶端代碼可以一致地處理單個對象和組合對象,無須關心自己處理的是單個對象,還是組合對象,這簡化了客戶端代碼; 2. 更容易在組合體內加入新的對象,客戶端不會因為加入了新的對象而更改源代碼,滿足“開閉原則”; **主要缺點是:** 1. 設計較復雜,客戶端需要花更多時間理清類之間的層次關系; 2. 不容易限制容器中的構件; 3. 不容易用繼承的方法來增加構件的新功能; 常見使用場景:如樹形菜單、文件夾菜單、部門組織架構圖、窗體程序中的簡單控件與容器控件等 #### **模式的結構** 組合模式包含以下主要角色。 1. **抽象構件(Component)角色**:它的主要作用是為樹葉構件和樹枝構件聲明公共接口,并實現它們的默認行為。在透明式的組合模式中抽象構件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由樹枝構件完成。 2. **樹葉構件(Leaf)角色**:是組合中的葉節點對象,它沒有子節點,用于實現抽象構件角色中 聲明的公共接口。 3. **樹枝構件(Composite)角色**:是組合中的分支節點對象,它有子節點。它實現了抽象構件角色中聲明的接口,它的主要作用是存儲和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。 組合模式分為透明式的組合模式和安全式的組合模式。 **透明式的組合模式** ``` /** *透明式合成模式 *抽象構件 */ interface Component { public function getComposite(); public function operation(); public function add(Component $component); public function remove(Component $component); public function getChildComposite(); } /** * 樹枝構件 */ class Composite implements Component { private $_children_composites=array(); //返回自己的實例 public function getComposite() { return $this; } // 示例方法,調用各個子對象的operation方法 public function operation() { foreach ($this->_children_composites as $composite) { $composite->operation(); } } //聚集管理方法 添加一個子對象 public function add(Component $component) { $this->_children_composites[] = $component; } //聚集管理方法 刪除一個子對象 public function remove(Component $component) { foreach ($this->_children_composites as $key => $row) { if ($component == $row) { unset($this->_children_composites[$key]); return TRUE; } } return FALSE; } // 聚集管理方法 返回所有的子對象 public function getChildComposite() { return $this->_children_composites; } } /** * 樹葉構件 */ class Leaf implements Component { private $_name; public function __construct($name) { $this->_name = $name; } public function operation() { echo $this->_name."<br>"; } public function getComposite() { return null; } public function add(Component $component) { return FALSE; } public function remove(Component $component) { return FALSE; } public function getChildComposite() { return null;//樹葉構件無子節點 } } class CompositePattern{ public static function main(){ // client $leaf1 = new Leaf('first'); $leaf2 = new Leaf('second'); $composite = new Composite(); $composite->add($leaf1); $composite->add($leaf2); $composite->operation(); $composite->remove($leaf2); $composite->operation(); } } CompositePattern::main(); ``` **安全式的組合模式** ``` /** * *安全式合成模式 */ interface Component { public function getComposite(); //返回自己的實例 public function operation(); } class Composite implements Component { // 樹枝組件角色 private $_composites=array(); public function getComposite() { return $this; } public function operation() { foreach ($this->_composites as $composite) { $composite->operation(); } } public function add(Component $component) { //聚集管理方法 添加一個子對象 $this->_composites[] = $component; } public function remove(Component $component) { // 聚集管理方法 刪除一個子對象 foreach ($this->_composites as $key => $row) { if ($component == $row) { unset($this->_composites[$key]); return TRUE; } } return FALSE; } public function getChild() { // 聚集管理方法 返回所有的子對象 return $this->_composites; } } class Leaf implements Component { private $_name; public function __construct($name) { $this->_name = $name; } public function operation() { echo $this->_name."被訪問了<br>"; } public function getComposite() { return null; } } class CompositePattern{ public static function main(){ // client $leaf1 = new Leaf('first'); $leaf2 = new Leaf('second'); $composite = new Composite(); $composite->add($leaf1); $composite->add($leaf2); $composite->operation(); echo "-----------<br />"; $composite->remove($leaf2); $composite->operation(); } } CompositePattern::main(); 結果: first被訪問了 second被訪問了 ----------- first被訪問了 ``` ## **組合模式的應用場景** 1. 在需要表示一個對象整體與部分的層次結構的場合。 2. 要求對用戶隱藏組合對象與單個對象的不同,用戶可以用統一的接口使用組合結構中的所有對象的場合。 ``` //抽象構件 Abstract class Component{ public $name; abstract function doSomething(); public function __construct($name){ $this->name = $name; } } //總經理 部門經理 主管等 樹枝構件 class Composite extends Component{ public $lever = 1; public $c_nodes = array(); public function getChildComposite(){ echo "<pre>"; print_r($this->c_nodes); } //添加子節點 public function add(Component $component){ $component->lever = $this->lever + 1; $this->c_nodes[] = $component; } public function doSomething(){ $nbsp=str_repeat("&nbsp;",($this->lever-1)*4); echo "{$nbsp}我是層級{$this->lever}:{$this->name}<br>"; } } //普通員工 樹葉構件 不能添加子節點 class Leaf extends Component{ public $lever; public function doSomething(){ $nbsp=str_repeat("&nbsp;",($this->lever-1)*4); echo "{$nbsp}層級{$this->lever}:{$this->name}(work)<br>"; } } $manager = new Composite("總經理"); $xgm = new Composite("銷售經理"); $sgm = new Composite("行政經理"); $staff = new Leaf("張三"); //組裝成樹 $manager->add($xgm); $manager->add($sgm); $sgm->add($staff); $staff2 = new Leaf("李四"); $sgm->add($staff2); $staff3 = new Leaf("王五"); $xgm->add($staff3); $manager->getChildComposite(); //遍歷樹 - 函數 function display(Composite $composite){ $composite->doSomething(); foreach($composite->c_nodes as $c_node){ //屬于枝葉執行doSomething 否則繼續回調displa函數 $c_node instanceof Leaf ? $c_node->doSomething() : display($c_node); } } display($manager); ``` 結果: ~~~ Array ( [0] => Composite Object ( [lever] => 2 [c_nodes] => Array ( [0] => Leaf Object ( [lever] => 3 [name] => 王五 ) ) [name] => 銷售經理 ) [1] => Composite Object ( [lever] => 2 [c_nodes] => Array ( [0] => Leaf Object ( [lever] => 3 [name] => 張三 ) [1] => Leaf Object ( [lever] => 3 [name] => 李四 ) ) [name] => 行政經理 ) ) 我是層級1:總經理 ????我是層級2:銷售經理 ????????層級3:王五(work) ????我是層級2:行政經理 ????????層級3:張三(work) ????????層級3:李四(work) ~~~ 實例2: ![](https://img.kancloud.cn/5c/4d/5c4d2aab0b864b3819857f722ed23c7c_486x321.png) ``` <?php //模型中所有的類都擴展自 Unit 類,同時,Army 和 TroopCarrier 類被設計成了組合對象,用于包含 Unit 對象。 //但是,我們也發現 ArcherUnit 和 LaserCannonUnit 類(稱為局部對象,也稱為樹葉對象,因為組合模式為樹形結構,組合對象為樹干,單獨存在的對象為樹葉,樹葉對象應為最小單元,其中不能包含其他對象。)不能包含其他 Unit 對象,但也實現了addUnit() 方法,這個問題我們后面討論。 /* 戰斗單元的抽象類 有一個抽象方法bombardStrength()方法用于設置戰斗單元的攻擊強度 */ abstract class Unit{ function getComposite(){ return null; } abstract function bombardStrength(); } //弓箭手 class Archer extends Unit{ function bombardStrength(){ return 4; } } //激光炮單位 class LaserCanonUnit extends Unit{ function bombardStrength(){ return 44; } } /* CompositeUnit 混合作戰單元類 因為CompositeUnit沒有實現bombardStrength()方法, 所以CompositeUnit聲明為抽象類abstract 戰斗單元為樹葉類時為了避免使用addUnit與removeUnit則通過下面抽象出的CompositeUnit類的getComposite */ abstract class CompositeUnit extends Unit{ private $units=array(); function getComposite(){ return $this; } protected function units(){ return $this->units; } function removeUnit(Unit $unit){ $units=array(); foreach ($this->units as $thisunit){ if(!unit!==$thisunit){ $units[]=$thisunit; } } $this->units=$units; } function addUnit(Unit $unit){ if(in_array($unit, $this->units,true)){ return; } $this->units[]=$unit; } } /** * 定義一個獨立的類(Army類)來組合戰斗單元。 * 戰斗集合的類 樹枝類 * 如果 Army(軍隊)類需要和其他Army類進行合并,同時,每個 Army 都有自己的 ID,這樣 Army 在以后還可以從整編中解散出來。 * 我們修改原來的 Army(軍隊)類,使其同時支持 Unit(單元)和 Army(軍隊)。 */ class Army extends CompositeUnit{ public $units=array(); //添加單位 function addUnit(Unit $unit){ if(in_array($unit, $this->units,true)){ return; } $this->units[]=$unit; } //移除單位 function removeUnit(Unit $unit){ $units=array(); foreach ($this->units as $thisunit){ if($unit!==$thisunit){ $units[]=$thisunit; } } $this->units=$thisunit; } //總攻擊強度 function bombardStrength(){ $ret=0; foreach ($this->units as $unit){ $ret+=$unit->bombardStrength(); } return $ret; } //添加陸軍 function addArmy(Army $army){ array_push($this->armies, $army); } } //運兵船 class TroopCarrier extends CompositeUnit{ function addUnit(Unit $unit){ if($unit instanceof Cavalry){//騎兵對象 throw new UnitException("不能將騎兵帶上船"); } Parent::addUnit($unit); } function bombardStrength(){ return 0; } } //騎兵對象 class Cavalry extends CompositeUnit{ function addUnit(Unit $unit){ } function removeUnit(Unit $unit){ } function bombardStrength(){ } } class UnitException extends Exception{ } class UnitScript{ //有兩個Unit類型的參數,第一個是新的Unit對象,第二個是之前的Unit對象 static function joinExisting(Unit $newUnit,Unit $oldUnit){ $comp; if(!is_null($comp=$oldUnit->getComposite())){ //如果第二個Unit對象是一個CompositeUnit對象,那么直接add $comp->addUnit($newUnit); }else { //如果第二個Unit對象不是一個CompositeUnit對象,那么創建一個Army對象,將兩個Unit存入這個Army對象 $comp=new Army(); $comp->addUnit($oldUnit); $comp->addUnit($newUnit); } return $comp; } } $main_army=new Army(); $main_army->addUnit(new Archer()); $main_army->addUnit(new LaserCanonUnit()); $sub_army=new Army(); $sub_army->addUnit(new Archer()); $sub_army->addUnit(new Archer()); $sub_army->addUnit(new Archer()); $main_army->addUnit($sub_army); $a=new TroopCarrier(); $b=$a->addUnit(new Archer()); //$b=$a->addUnit(new Cavalry()); //print_r($main_army->units); print "攻擊強度:{$main_army->bombardStrength()}<br>"; //也可以這樣 UnitScript::joinExisting($main_army, $sub_army); $main=new Army(); $main->addUnit(new Archer()); $sub=new Army(); $sub->addUnit(new LaserCanonUnit()); $all=UnitScript::joinExisting($main, $sub); print "攻擊強度:{$all->bombardStrength()}<br>"; ``` 結果: ``` 攻擊強度:60 攻擊強度:48 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看