选择DST!支持DST!

查看完整版本: [PHP设计模式]Composite(组合)模式范例

loveapple 2007-8-23 16:56

[PHP设计模式]Composite(组合)模式范例

来自于:[url]http://bbs.loveapple.cn/loveappleSearch.php?formhash=ddc13296&q=%5BPHP%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%5DComposite%28%E7%BB%84%E5%90%88%29%E6%A8%A1%E5%BC%8F%E8%8C%83%E4%BE%8B&sa=%E6%8F%90%E4%BA%A4&domains=bbs.loveapple.cn&sitesearch=bbs.loveapple.cn&client=pub-2097865745512830&forid=1&ie=UTF-8&oe=UTF-8&cof=GALT%3A%23008000%3BGL%3A1%3BDIV%3A%23336699%3BVLC%3A663399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699%3BALC%3A0000FF%3BLC%3A0000FF%3BT%3A000000%3BGFNT%3A0000FF%3BGIMP%3A0000FF%3BFORID%3A11&hl=zh_CN[/url]
|/W4|w0Ea+^+W$AZ
(Y!d,rfF JY#M$x Composite模式定义:
/\)Mu D6F4i? 将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.8MrH X7s%H

ec4}e5g%t0U` j Composite 比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。gj)J$A4Rb

5P'^@%Wt{}a3k 所以Composite模式使用到Iterator模式,和Chain of Responsibility模式类似。!A@,LO%V~
A"Z;w AS$?)L
Composite好处:
,q7{#@rB$yM p hG 1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。)l0SJM)V'Q
2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。s`Q t K&H

Y*P5I%M+H'A 如何使用Composite?
7Ir+cVl!vk 首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component)
OL6p:n*X+B1z!{kX k*jw?_3O0I
[[i] 本帖最后由 loveapple 于 2007-9-8 01:33 编辑 [/i]]

loveapple 2007-8-23 16:56

[code]interface Component{
+}tUwuD*A1Ov.g W         public function dispName();u&B"w9QB
        public function setParent(Category $category);(tfw'ti'fVv
        public function getParent();tjz ]N7x
        public function getName();
6B/x z C2n a         public function setName($name);
&vZ$[(w PBl4Q }(},[y&V#M({|

Y'o4yt,^ p"] class Composite implements Component {
'{MD'I3N7c3{G         private $name;.vr-gH ?#q
        private $subList;g:h8xo4e
        private $parent;G7qu3?H2{
        public function __construct($name){d r0H+o+^_M0L
                $this->setName($name);Zz#Qd P(`3p w
        }
6k%hb)O;?9s6v         public function dispName(){;I'U+H0\!{.|9X6^h
                print $this->name."\n";1~)I/hT)y JW
        }
u7U0km F4@ f)r _;Nv         public function setName($name){
^5A@:jNsn.o                 $this->name = $name;
1f(T:B5Rw5h         }
%fn"sR)_w/t[/zy:v         public function getName(){3cS,UW7C F%J?^
                return $this->name;IKT!w,lCh'b
        }_8pes,@;q4^yJ?
        public function setSubList(array $subList){
$Yg[g:a[F                 $this->subList = $subList;#X_wgum }D5q
        } E7\0Gw Y
        public function getSubList(){zG+r:rh*d|
                return $this->subList;
d#P!N6jSf}C3[         }0u2^.h.p2O Q
        public function addSubList(AbstractContents $contents){(Y$[$Gb&sE?
                $this->subList[] = $contents;+B4zFj'X5K6r
                $contents->setParent($this);8BvX0n-C4eB G
        }A)q5l+[Jx1o8D
        public function setParent(Category $category){%o(I$t6{7\j~
                $this->parent = $category;
n;tp7bxP+[w         }
RX9g@:e8|:t"j%n:}$J         public function getParent(){
KNg z V d4r K4_,R                 return $this->parent; h*hqwg3H*N
        }I[]M/B$sD
        public function disList($parent=""){      
6l/WJDa-vk3G                 if(is_null($this->subList)){&H(d^h;Q7Oh
                        return;{{#]hV'gP/S@
                }
s4gT8C[(O!k6[                 foreach ($this->subList as $sub){
n+th5r.yE,f                         print $parent."/".$sub->getName()."\n";G8@*db;Wz1pF*TyH
                        if($sub instanceof Category){
%s E Z)Lt&e6A                                 $sub->disList($parent."/".$sub->getName());PUYg3h;EzVg
                        }
(G N*oxC[vT1j%i S&u                 },u3E(qg ^d^7Y
        }Ml Vh8? wh
}
'U)[v,@E2DO,U class Leaf implements Component {
M!H0F/n5JL T         private $name; P5KT {]
        private $parent;hCCPk Z"m1g
        public function __construct($name){1C ]n)U o.~? N\
                $this->setName($name);
.bTX]nA2q+t         } kC+n!LQv#v-PX
        public function dispName(){%x K6bc1R c
                print $this->name."\n";
xu5}%?q`7a         }
D O.i&]Zgm4nm         public function setName($name){&Bs_9opt
                $this->name = $name;
z"\l`$fJ         }
J~/]8_!OU r%bFy         public function getName(){
(I*c3YX%M1l1g                 return $this->name;a[@+{%EP3U
        };QAK%h.U Q6vr`-I?M
        public function setParent(Category $category){6EbsVI
                $this->parent = $category;ffTe5U&V
        }
@WSprV         public function getParent(){
.ffdFt2X                 return $this->parent;F,]l9V9A j%H6^cU
        }:Q5_-y%PZH:l7C
}[/code]

loveapple 2007-8-23 16:57

这个程序是我跟一个朋友争论如何用PHP写文档目录树时作的一个范例程序。
#u#{ Y/rr1eD\O5N 文件系统的文件夹与文件之间的关系,&K[5q;O1y
论坛分区、论坛、自论坛与帖子之间的关系, `"E4v@vR
shopping程序中商品的各个层次的分区与商品的关系,
!M R7j[ |X 文章系统的文章的分区与文章之间的关系,-}Q1tA!KF
要实现这些目录树功能,他们都有一个共同的特性。
`t1^"sn1E;o*A1| 用目标指向的思维方式去解释他们,可以非常容易的利用其共通特性简化代码。 W3z#hvN2Et
8{$_(VMz6N_t3e.sE
[[i] 本帖最后由 loveapple 于 2007-8-23 16:59 编辑 [/i]]
页: [1]
查看完整版本: [PHP设计模式]Composite(组合)模式范例