目录  7、组合模式 7.1 组合模式(Composite) 7.2 叉树结构 7.3 文件系统 7.4 目录树展示 7.5 自相似性的涌现 7.6 组合模式的各角色定义 7.7 组合           
  
 
 7、组合模式  
 7.1 组合模式(Composite)  
是针对由多个节点对象(部分)组成的树形结构 的对象(整体)而发展出的一种结构型设计模式 它能够使客户端在操作整体对象 或者其下的每个节点对象 时做出统一的响应 ,保证树形结构对象使用方法的一致性 整体和部分,有类似结构 测试类结构     
 7.2 叉树结构  
某些具有从属关系的事物 之间存在着一定的相似性  不管从哪个层级,我们都会得到一个固定的结构  这种结构类似于经典的“叉树”结构:无论数据元素是“根”“枝”,还是“叶”,甚至是整体的树,都具有类似的结构  我们可以用组合模式来表达“部分/整体”的层次结构 ,提取并抽象其相同的部分 ,特殊化其不同的部分 ,以提高系统的可复用性与可扩展性   
 7.3 文件系统  
以类似于树结构的文件系统的目录结构为例 抽象节点类Node 定义一个抽象的“节点”类来模糊“文件夹”与“文件” 构造方法中接收并初始化已定义的节点名 ,否则不允许节点被创建,这也是可以固化下来的逻辑 。声明抽象方法,模糊行为并留给子类去实现      
package  composite ; 
public  abstract  class  Node  { protected   String  name; public  Node ( String  name)  { this . name =  name; } protected  abstract  void  add ( Node  child)  throws  Exception ; 
} 
  
节点实现类1:文件夹类Folder 文件夹类继承了抽象节点类Node 文件夹下级可以包含任意多个文件夹或者文件:次级节点列表List      
package  composite ; import  java. util.  ArrayList ; 
import  java. util.  List ; 
public  class  Folder  extends  Node  { List < Node >   children =  new  ArrayList < > ( ) ; public  Folder ( String  name)  { super ( name) ; } @Override protected  void  add ( Node  child)  { children. add ( child) ; } 
} 
  
 
package  composite ; 
public  class  File  extends  Node  { public  File ( String  name)  { super ( name) ; } @Override protected  void  add ( Node  child)  { System . out. println ( "文件类型不能添加子节点" ) ; } 
} 
  
 
package  composite ; 
public  class  Client  { public  static  void  main ( String [ ]  args)  throws  Exception  { Node  driveD =  new  Folder ( "测试盘" ) ; Node  doc =  new  Folder ( "文档" ) ; doc. add ( new  File ( "简历.doc" ) ) ; doc. add ( new  File ( "项目介绍.ppt" ) ) ; driveD. add ( doc) ; Node  music =  new  Folder ( "音乐" ) ; Node  jay =  new  Folder ( "周杰伦" ) ; jay. add ( new  File ( "双截棍.mp3" ) ) ; jay. add ( new  File ( "告白气球.mp3" ) ) ; jay. add ( new  File ( "听妈妈的话.mp3" ) ) ; Node  jack =  new  Folder ( "张学友" ) ; jack. add ( new  File ( "吻别.mp3" ) ) ; jack. add ( new  File ( "一千个伤心的理由.mp3" ) ) ; music. add ( jay) ; music. add ( jack) ; driveD. add ( music) ; } 
} 
  
 7.4 目录树展示  
要体现出组合模式的优势还在于如何运用这个树结构 分级展示整棵目录树  输出节点名称(文件夹名/文件名)之前加上数个空格以表示不同层级 修改抽象节点类Node并加入展示方法tree()       protected  void   tree ( int  space)  { for  ( int  i =  0 ;  i <  space;  i++ )  { System . out. print ( "    " ) ; } System . out. println ( name) ; } protected  void  tree ( )  { this . tree ( 0 ) ; } 
  节点实现类File和Folder重写展示方法,Folder还要展示其子级       @Override public  void  tree ( int  space)  { super . tree ( space) ; space++ ; for  ( Node  child :  children)  { child. tree ( space) ; } } 
  
@Override 
public  void  tree ( int  space) { super . tree ( space) ; 
} 
  客户端在任何一级节点上只要调用其展示方法并传入当前目录所需的空格偏移量,就可出现树形列表了   	driveD. tree ( ) ; 
  空格偏移量这个必传参数,可以为抽象节点类添加一个无参的展示方法,默认为0     
 7.5 自相似性的涌现  
组合模式将树形结构的特点发挥得淋漓尽致 作为最高层级抽象的抽象节点类 (接口)泛化了所有节点类 ,使任何“整体”或“部分”达成统一  枝(根)节点与叶节点的多态化实现以及组合关系进一步勾勒出的树形结构      
 7.6 组合模式的各角色定义  
Component(组件接口): 所有复合节点与叶节点的高层抽象 ,定义出需要对组件操作的接口标准  如抽象节点类Node,具体使用接口还是抽象类需根据具体场景而定。    Composite(复合组件): 包含多个子组件对象(可以是复合组件或叶端组件)的复合型组件,并实现组件接口中定义的操作方法。 如:“根节点/枝节点”的文件夹类Folder    Leaf(叶端组件): 不包含子组件的终端组件,同样实现组件接口中定义的操作方法。 如: “叶节点”的文件类File    Client(客户端): 按所需的层级关系部署相关对象并操作组件接口所定义的接口,即可遍历树结构上的所有组件      
 7.7 组合  
类似的结构总是在重复、迭代地显现出某种自似性 其部分与整体一致的呈现与“组合模式”如出一辙