<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>

                >組合模式 (Composite Pattern):將對象組合成樹形結構以表示“部分整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。組合模式也叫合成模式,有時候又叫做部分-整體模式。 ## (一)為什么需要組合模式 1,使我們在樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以像處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。 2,組合模式讓你可以優化處理遞歸或分級數據結構。 ## (二)組合模式UML圖 ![](https://box.kancloud.cn/4a9ba41d428626851023c72ebe559639_909x579.png) Component是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行為。聲明一個接口用于訪問和管理Component子部件。 Leaf 在組合中表示葉子結點對象,葉子結點沒有子結點。 Composite定義有枝節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如增加(add)和刪除(remove)等。 ## (三)簡單實例 如果我們在做一個OA系統,公司的人事管理該如何設計呢。傳統的就是樹狀結構。經理下面有部門主管,然后是員工。 ![](https://box.kancloud.cn/aa7349fd7778b0a5b492bb04da346f3a_693x341.png) 人事部門圖 <?php class Manager{ public $name; protected $c_nodes = array();//存放子節點,部門經理,普通員工等 public function __construct($name){ $this->name = $name; } //添加部門經理 public function addGm(GM $gm){ $this->c_nodes[] = $gm; } //添加普通員工 public function addStaff(Staff $staff){ $this->c_nodes[] = $staff; } //獲取全部子節點 public function get_C_nodes(){ return $this->c_nodes; } } //部門經理 就用general manager 簡寫 GM Interface Gm{ public function add(Staff $staff); public function get_c_nodes(); } //銷售經理 class Sgm implements Gm{ public $name; protected $c_nodes = array(); public function __construct($name){ $this->name = $name; } //添加員工 public function add(Staff $staff){ $this->c_nodes = $staff; } //獲取子節點 public function get_C_nodes(){ return $this->c_nodes; } //區別于其他經理,銷售經理有一個銷售方法 public function sell(){ echo "安利一下我司的產品"; } } //員工接口 Interface staff{ public function work(); } //銷售部員工 class Sstaff implements staff{ public $name; public function work(){ echo '在銷售經理帶領下,安利全世界'; } } //實例化 $manager = new Manager("總經理"); $sgm = new Sgm("銷售經理"); $staff = new Sstaff("何在"); //組裝成樹 $manager->addGm($sgm); $sgm->add($staff); 我們想象一下,如果我們的層級非常深,如銷售經理下面還有,銷售主管,分區經理,分區主管。那怎么辦?我們new的時候,就要new很多不同的類。而且如果要加一個任職期限的屬性,還得每個類去添加一遍。 我們想做的是,可以把樹形結構,當成“部分-整體結構”來處理,通俗地講,就是把一個樹形結構當成一個關系型的結構。例如:數據庫存儲的一行行的方式。找了張圖,清楚些。 ![](https://box.kancloud.cn/76693537f7dbebb3e802a86d3a7e3ec8_462x215.png) 上面這張圖把中國 -湖南-(長沙)(衡陽)-這個樹狀圖以關系型的層級方式存儲于數據庫中。對于公司人事,其實我們也是可以用這種方法的。那就是利用組合模式。再去看一眼UML圖把和人事管理圖吧。我們發現總經理和部門經理還是有很多相同的地方。組合模式主要就是把根節點和所有樹枝節點歸結到一起去,這樣就隱藏了樹形的層級。 <?php //抽象構件 Abstract class Component{ public $name; abstract function doSomething(); public function __construct($name){ $this->name = $name; } } //普通員工 樹葉構件 不能添加子節點 class Leaf extends Component{ public $lever; public function doSomething(){ echo "層級--{$this->lever}--work"; } } //總經理 部門經理 主管等 樹枝構件 class Composite extends Component{ public $c_nodes = array(); public $lever = 1; //添加子節點 public function add(Component $component){ $component->lever = $this->lever + 1; $this->c_nodes[] = $component; } public function doSomething(){ echo "我是層級--{$this->lever}--".PHP_EOL; } } $manager = new Composite("總經理"); $sgm = new Composite("銷售經理"); $staff = new Leaf("何在"); //組裝成樹 $manager->add($sgm); $sgm->add($staff); 這樣,我們就把根節點(總經理)和所有樹枝節點(部門經理,主管)的樹枝結構隱藏了,通過$lever屬性來區分。如果對于不同樹枝節點有不同的方法,我們也可以在Composite 類中的doSomething()方法中延遲綁定具體的方法實現,使不同層級具有不同能力 public function doSomething(){ switch($this->lever){ case 1:$this->manager(); break; case 2:$this->sell(); } } private function manager(){} private function sell(){} 當然,當層級太深時,若有多個層級有相同的doSomething能力。這種方法還是可以的。但是當層級太深且不同層級具有不同的doSomething能力時,就會導致一個類中空置了多個不用的private方法,而doSomething只調用一個。 $lever 的另一個功能就是便于遞歸遍歷出所有公司人員 //遍歷樹 - 函數 function display(Composite $composite){ $composite->doSomething(); foreach($composite->c_nodes as $c_node) $c_node instanceof Leaf ? $c_node->doSomething() : display($c_node); } display($manager); 當然這種遍歷方法只能前序遍歷,即從根節點總經理向下找,沒法從任何一個員工向上找出他的上級。如果,你想實現后序遍歷,可以在Component類中添加一個parent屬性,并在composite 的add方法中設置子節點的parent屬性。 組合模式也分為透明模式和安全模式,上面的例子是安全模式。透明模式是把composite的方法也放到抽象類component中。 >有許多關于分級數據結構的例子,使得組合模式非常有用武之地。關于分級數據結構的一個普遍性的例子是你每次使用電腦時所遇到的:文件系統。文件系統由目錄和文件組成。每個目錄都可以裝內容。目錄的內容可以是文件,也可以是目錄。按照這種方式,計算機的文件系統就是以遞歸結構來組織的。如果你想要描述這樣的數據結構,那么你可以使用組合模式Composite。
                  <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>

                              哎呀哎呀视频在线观看