组合模式
-
定义:
组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次。组合模式对单个对象(叶子对象)和组合对象(组合对象)具有一致性,它将对象组织到树结构中,可以用来描述整体与部分的关系。同时它也模糊了简单元素(叶子对象)和复杂元素(容器对象)的概念,使得客户能够像处理简单元素一样来处理复杂元素,从而使客户程序能够与复杂元素的内部结构解耦。
叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。
-
使用场景:
-
在具有整体和部分的层次结构种希望通过一种忽略整体与个体之间差异的,客户端一致对待的情况。
-
在一个使用面向对象语言开发的系统中需要处理一个树形结构的。
-
在一个系统中能分离出叶子和容器的,而且他们的类型还固定不变,需要增加一些新的类型
-
-
UML:
- Component:它可以是接口或者抽象类,为叶子构建和子容器构建对象声明接口,在该角色中可以包含所有子类共有的行为的实现和声明。在抽象构建中定义了访问及管理它的子构件的方法,如增加子构件,删除子构件,获取子构件等。
- Leaf:叶子构建可以说就是各种类型的文件!叶子构建没有子构件。它实现了抽象构建中的定义的行为。对于那些访问子容器,删除子容器,增加子容器的就报错。
- Composite:它在组合模式中表示容器节点对象,容器结点是子节点,可以是子容器,也可以是叶子构建,它提供一个集合来存储子节点。
-
优点:
- 可以清楚地定义分层次的复杂类型,表示对象的全部层次或者部分层次 ,它让客户端忽略了层次的差异,方便对整个层次经行控制。
- 客户端可以一致的使用一个组合模式或对单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端的代码。
- 在组合模式中增加新的容器构件和叶子构件都很方便,无需对现有类库进行任何修改,符合开闭原则。
- 为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合可以形成复杂的树形机构,但对树形结构的控制却很简单。
-
缺点:
无法满足一些特殊要求,在增加新的构件时就比较难。而且难以限定,有时候希望在一个容器种能有某些特定的对象,例如在某个文件夹只能有image或者gif等。同时使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联
-
样例:
public abstract class Component{ //这个是容器类的抽象类,定义好行为,定义创建移除子容器的方法抽象的。 public abstract void addComposite(Component c); //添加成员 public abstract void removeComposite(Component c);//移除成员 public abstract Component getComposite(int i);//获取子容器 public abstract void operation();//业务方法 }
public class Leaf extends Component{ //首先重写component的方法 //叶子节点关键点在于业务 public void Operation(){ System.out.print("业务方法"); } public void addComponent(Component c){ //提示报错呗 。 System.out.print("不是子容器"); } public void removeComponent(Component c){ //提示报错呗 。 System.out.print("不是子容器"); } public Component addComponent(int c){ //提示报错呗 。 System.out.print("不是子容器"); return null; } }
public class Composite extends Component{ //首先来一个存储的集合 private ArrayList<Component> list = new ArrayList<Component> ; public void addComponent(Component c){ list.add(c); } public void removeComponent(Component c){ list.remove(c); } public Component getComponent(int c){ Component c1 =list.get(c); return c1; } public void operation(){ for(Object obj:list){ ((Component)obj).operation(); } } }