设计模式8——组合模式(结构型模式)

本文在书写过程中参考了以下文章及《大话设计模式》:

https://www.cnblogs.com/snaildev/p/7647190.html

https://www.cnblogs.com/lfxiao/p/6816026.html

https://blog.csdn.net/CYL926/article/details/79134640

组合模式的概念

组合模式(Composite Pattern)也称为部分整体模式(Part-Whole Pattern),结构型模式之一。

组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。

Android 中 View 和 ViewGroup 的实现就应用了组合模式。

UML

组合模式

 

      在组合模式结构图中包含如下几个角色:

      ● Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。

      ● Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。

      ● Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

代码实现

对于组合模式中的抽象构件角色,其典型代码如下所示:

abstract class Component {  
    public abstract void add(Component c); //增加成员  
    public abstract void remove(Component c); //删除成员  
    public abstract void doSomething();  //业务方法  
} 

 如果继承抽象构件的是叶子构件,则其典型代码如下所示:

class Leaf extends Component {  

    public Leaf(String name){
        super(name);
    }
    public void add(Component c) {   
        //异常处理或错误提示   
    }     
          
    public void remove(Component c) {   
        //异常处理或错误提示   
    }  
      
      
    public void doSomething() {  
        //叶子构件具体业务方法的实现  
    }   
} 

 如果继承抽象构件的是容器构件,则其典型代码如下所示

class Composite extends Component {  

    public Composite(String name){
        super(name);
    }
    private List<Component> list = new ArrayList<Component>();  
      
    public void add(Component c) {  
        list.add(c);  
    }  
      
    public void remove(Component c) {  
        list.remove(c);  
    }  
      
      
    public void doSomething() {  
        //容器构件具体业务方法的实现  
        //递归调用成员构件的业务方法  
        for(Object obj:list) {  
            ((Component)obj).operation();  
        }  
    }     
}

 在容器构件中实现了在抽象构件中声明的所有方法,既包括业务方法,也包括用于访问和管理成员子构件的方法,如add()、remove()等方法。需要注意的是在实现具体业务方法时,由于容器构件充当的是容器角色,包含成员构件,因此它将调用其成员构件的业务方法。

static void Main(string[] args)
{
    // 生成树根,并为其增加两个叶子节点
    Composite.Composite root = new Composite("Root");
    root.Add(new Leaf("Leaf A in Root"));
    root.Add(new Leaf("Leaf B in Root"));
 
    // 为根增加两个枝节点
    Composite.Composite branchX = new Composite.Composite("Branch X in Root");
    Composite.Composite branchY = new Composite.Composite("Branch Y in Root");
    root.Add(branchX);
    root.Add(branchY);
 
    // 为BranchX增加页节点
    branchX.Add(new Leaf("Leaf A in Branch X"));
 
    // 为BranchX增加枝节点
    Composite.Composite branchZ = new Composite.Composite("Branch Z in Branch X");
    branchX.Add(branchZ);
 
    // 为BranchY增加叶节点
    branchY.Add(new Leaf("Leaf in Branch Y"));
 
    // 为BranchZ增加叶节点
    branchZ.Add(new Leaf("Leaf in Branch Z"));
 
    // 显示树
    root.doSomething();
}

 

   适用场景

      在以下情况下可以考虑使用组合模式:

      (1) 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。

      (2) 在一个使用面向对象语言开发的系统中需要处理一个树形结构。

      (3) 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值