组合模式
组合模式(composite),将对象组合成树形结构以表示 '部分-整体' 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
何时使用组合模式:需求中体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同(整体与部分可以一致被对待),统一地使用组合结构中的所有对象时,就应该考虑用组合模式。
透明方式与安全方式:
透明方式也就是说在Component中声明所有用来管理子对象的方法。这样实现Component接口的所有子类都具备了相同的方法。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf叶节点类本身不需要所有的方法,所以实现全部接口的方法,有些是没有意义的。
安全方式 就是Component 接口中只声明叶节点和树枝节点共同的方法,叶节点不需要的方法不声明。而是在Composite树枝节点来声明所有用来管理子类对象的方法。不过不够透明,所以叶节点和树枝节点类将不具有相同的接口,客户端的调用需要做相应的判断,这将带来不便。
组合模式的好处
基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
组合模式让客户可以一致地使用组合结构和单个对象。(不用选择判断语句来区分叶节点和分支节点)
Component抽象类
package composite; /** * 对象声明接口,声明所有类的接口 * 透明方式 * @author 煞笔 * */ public abstract class Component { String name; public Component(String name) { super(); this.name = name; } public abstract void add(Component c); public abstract void remove(Component c); public abstract void doWork(); public abstract void display(int dept); }
Composite类
package composite; import java.util.ArrayList; import java.util.List; /** * 定义子节点的行为 * @author 煞笔 * */ public class Composite extends Component { private List<Component> list = new ArrayList<Component>(); public Composite(String name) { super(name); } @Override public void add(Component c) { list.add(c); } @Override public void remove(Component c) { list.remove(c); } @Override public void doWork() { for(Component c:list){ if(c instanceof Composite){ System.out.println("在这里处理树枝节点的业务逻辑等"+c.name); c.doWork(); } } } @Override public void display(int dept) { StringBuffer sb = new StringBuffer(); for(int i=0;i<dept;i++){ sb.append(new String("-")); } System.out.println(sb.toString()+name); for(Component c:list){ c.display(dept+2); } } }
Leaf类
package composite; /** * 叶节点,没有子节点 * 方法:add/doWork/remove 没有意义,但这样做是实现透明方式,可以消除叶节点和枝节点对象在抽象层次的区别,它们具备完全一致的接口。 * @author 煞笔 * */ public class Leaf extends Component { public Leaf(String name) { super(name); } @Override public void add(Component c) { } @Override public void remove(Component c) { } @Override public void doWork() { } @Override public void display(int dept) { StringBuffer sb = new StringBuffer(); for(int i=0;i<dept;i++){ sb.append(new String("-")); } System.out.println(sb.toString()+name); } }
Business类
package composite; public class Business { public static void main(String[] args) { Composite root = new Composite("root"); root.add(new Leaf("root叶节点A")); Composite A = new Composite("root大树主干A"); Composite A1 = new Composite("A树枝"); A.add(A1); A.add(new Leaf("A叶节点")); root.add(A); root.add(new Leaf("root叶节点B")); Composite B = new Composite("root大树主干B"); Composite B1 = new Composite("B树枝"); Composite B11 = new Composite("B1树枝"); B11.add(new Leaf("B1叶节点")); B1.add(B11); B.add(B1); B.add(new Leaf("B叶节点")); root.add(B); root.add(new Leaf("root叶节点C")); root.display(1); root.doWork(); } }