设计模式-组合模式

组合模式(Composite Pattern)

将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,组合模式定义了如何将容器对象和叶子对象进行递归组合,使用户对单个对象和组合对象具有一致的访问性。

组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

组合模式主要包含如下几个角色:

  1. 抽象构件(Component)角色:组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
  2. 树叶构件(Leaf)角色:叶子对象。叶子结点没有子结点。
  3. 树枝构件(Composite)角色 / 中间构件:容器对象,定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

透明式的组合模式的结构图

实例

集合c0的树状图

​ 请求从上到下沿着树进行传递,直到树的尽头。作为客户,只需要关心树最顶层的组合对象,客户只需要请求这个组合对象,请求便会沿着树往下传递,依次到达所有的叶对象。

抽象构件

//
public interface Component {
    public void add(Component c);
    public void remove(Component c);
    public Component getChild(int i);
    public void operation();
}

树叶构件

public class Leaf implements Component {
    private String name;
    public Leaf(String name) {
        this.name = name;
    }
    public void add(Component c) {
    }
    public void remove(Component c) {
    }
    public Component getChild(int i) {
        return null;
    }
    public void operation() {
        System.out.println("树叶" + name + ":被访问!");
    }
}

树枝构件

public class Composite implements Component {
    private ArrayList<Component> children = new ArrayList<Component>();
    public void add(Component c) {
        children.add(c);
    }
    public void remove(Component c) {
        children.remove(c);
    }
    public Component getChild(int i) {
        return children.get(i);
    }
    public void operation() {
        for (Object obj : children) {
            ((Component) obj).operation();
        }
    }
}

Test

public class MyTest {
    public static void main(String[] args) {
        Component c0 = new Composite();
        Component c1 = new Composite();
        Component leaf1 = new Leaf("1");
        Component leaf2 = new Leaf("2");
        Component leaf3 = new Leaf("3");
        c0.add(leaf1);
        c0.add(c1);
        c1.add(leaf2);
        c1.add(leaf3);
        c0.operation();
    }
}

程序运行结果如下:

树叶1:被访问!
树叶2:被访问!
树叶3:被访问!

以上为透明式组合模式。客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。对于客户而言,都是Compoent对象,具体的类型对于客户端而言是透明的,是无须关心的。

其缺点是:树叶构件本来没有 Add()、Remove() 及 GetChild() 方法,调用会导致编译错误。因此透明方式会带来一些安全性问题。

因此还有一种安全模式的组合模式。

它要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。安全式合成模式的缺点是不够透明,因为树叶类和树枝类将具有不同的接口。具体实现方法为:去掉抽象类(Component)的方法,让树枝类(Composite)添加对应的方法,树叶类(Leaf)不写其他方法。

但是对于合成模式而言,在安全性和透明性上,会更看重透明性,毕竟合成模式的目的是:让客户端不再区分操作的是树枝对象还是树叶对象,而是以一个统一的方式来操作。

因此在使用合成模式的时候,建议多采用透明性的实现方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值