一天学习一个设计模式之组合模式

   组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

  

实现代码如下:

 1 /**
 2  *  Component为组合中的对象声明接口,在适当情况下,实现所有类共有的接口的默认行为
 3  */
 4 abstract class Component {
 5     String name;
 6     public Component(String name){
 7         this.name=name;
 8     }
 9     public abstract void add(Component c);
10     public abstract void remove(Component c);
11     public abstract void foreach();
12 }
 1 /**
 2  * 组合类 定义有枝节点行为,用来存储子部件,实现Component中与子部件有关的操作
 3  */
 4 public class Composite extends Component {
 5     // 用来保存节点的子节点
 6     private List<Component> child=new ArrayList<>();
 7 
 8     public Composite(String name) {
 9         super(name);
10     }
11     // 添加节点 添加部件
12     @Override
13     public void add(Component c) {
14         child.add(c);
15     }
16     // 删除节点 删除部件
17     @Override
18     public void remove(Component c) {
19         child.remove(c);
20     }
21     // 遍历子节点
22     @Override
23     public void foreach() {
24         System.out.println("节点名:	"+name);
25         for (Component c:child
26              ) {
27             c.foreach();
28         }
29     }
30 }
 1 /**
 2  * 组合部件类 叶节点对象,没有子节点
 3  */
 4 public class Leaf extends Component {
 5 
 6     public Leaf(String name) {
 7         super(name);
 8     }
 9 
10     // 叶子节点不具备添加的能力,所以不实现
11     @Override
12     public void add(Component c) {
13 
14     }
15     // 叶子节点不具备添加的能力必然也不能删除
16     @Override
17     public void remove(Component c) {
18 
19     }
20     // 叶子节点没有子节点所以显示自己的执行结果
21     @Override
22     public void foreach() {
23         System.out.println("tself name-->"+this.name);
24     }
25 }

客户端

public class Client {
    public static void main(String[] args) {
        // 构造根节点
        Component component=new Composite("根结点");
        Component child=new Composite("一级子节点child");
        Component child_1=new Leaf("一级子节点child之子节点一");
        Component child_2=new Leaf("一级子节眯child之子节点二");
        child.add(child_1);
        child.add(child_2);
        Component child2=new Composite("一级子节点child2");
        component.add(child);
        component.add(child2);
        component.foreach();
    }
}

透明方式与安全方式

  “树可能有无数的分枝,但只需要反复用Composite就可以实现树状结构了。“

  ”为什么Leaf类当中也有Add和Remove,树叶不是不可以再长分枝吗?“

  ”是的,这种方式叫做透明模式,也就是说Component中声明的所有用来管理子对象的方法,其中包括Add,Remove等。这样实现Component接口所有子类都具备了Add和Remove。这样

做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以实现它没有意义。“

  ”那么如果我不希望做这样的无用功呢?也就是Leaf类当中不用Add和Remove方法,可以吗?“

  ”当然可以,那么就需要安全方式,也就是在Component接口中不去声明 Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Component声明所有用来管理子类对象的方法,这样做就不会出现刚才提到的问题,不过由于不够透明,所以树叶和树枝将不具有相同的接口,客户端的调用需要做出相应的判断,带来了不便。“

  ”那我喜欢透明模式,那样就不用做任何判断了。"     --摘自《大话设计模式》

何时使用组合模式

  当你发现需求中是体现部分与整体层次的结构是地,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

组合模式的好处

  基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象。这样用户是不用关系到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。组合模式让客户可以一致地使用组合结构和单个对象。

原文地址:https://www.cnblogs.com/gousheng107/p/8023898.html