组合模式

意图

将对象组合成树型结构以表示“部分-整体”的层次结构。Composite使得或用户对单个对象和组合对象的使用具有一致性。

结构图:

 组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。

  • Component(组合部件):抽象角色,为要组合的对象提供统一的接口;
  • Leaf(叶子):在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图元对象的行为。
  • Composite(树枝):定义有子组件的那些组件的行为;存储子组件;在Component接口中实现与子组件有关的操作。
  • Client:通过Component接口操纵组合组件的对象。

有透明式组合模式,安全式组合模式

透明式:在Component中声明所有来管理子对象的方法,其中包括Add,Remove等。这样实现Component接口的所有子类都具备了Add和Remove方法。这样做的好处是叶结点和枝结点对于外界没有区别,它们具备完全一致的接口。但其缺点是:叶子构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。

package composite;
import java.util.ArrayList;
public class CompositePattern
{
    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(); 
    }
}
//抽象构件
interface Component
{
    public void add(Component c);
    public void remove(Component c);
    public Component getChild(int i);
    public void operation();
}
//树叶构件
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+":被访问!"); 
    }
}
//树枝构件
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();
        }
    }    
}
树叶1:被访问!
树叶2:被访问!
树叶3:被访问!

安全式:只在Component声明共有的方法,leaf和composite实现各自的方法,这样做就不会出现上面的问题,不过由于不够透明,所有树叶和树枝类将不具有相同的接口,客户端调用需要做相应的判断,带来不方便。

组合模式使用场景

  • 想表示一个对象整体或部分的层次结构。
  • 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

优缺点

优点:

  1. 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
  2. 将”客户代码与复杂的对象容器结构“解耦。
  3. 可以更容易地往组合对象中加入新的构件。

缺点:使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。

 总结

Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转为“一对一”,使得客户代码可以一致地(复用)处理对象和对象容器,无需关心处理的是单个对象,还是组合对象。

将“客户代码与复杂的对象容器结构”解耦,是Composite的核心思想,解耦之后,客户代码将与纯粹的抽象接口--而非对象容器的内部实现结构--发生依赖,从而更能应对变化。

Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可以使用缓存技巧来改善效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值