组合模式

树形结构在软件中十分常见,如操作系统中的文件结构,文件夹包含文件和子文件夹,而子文件夹又包含文件和子子文件夹,像这样的结构称为树形结构。在树形结构中,文件夹或子文件夹称为容器(Container);而不同类型的文件称为叶子(Leaf)。在树形结构中,由于容器对象和叶子对象在功能上的区别,导致必须有区别地对待容器对象和叶子对象,这将使程序变得复杂。而实际开发中,我们更希望一致地处理它们,由此引出了组合模式。通过组合模式,可以让叶子对象和容器对象的使用具有一致性

 

组合模式(Composite Pattern):将多个对象组合成树形结构,以表示“整体-部分”的层次关系。组合模式对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性。组合模式又称为“整体-部分”(Part-Whole)模式。是一种对象结构型模式

 

组合模式结构包含3个角色

抽象构件(Component):是接口或抽象类,定义了子类共有的行为

叶子构件(Leaf):表示叶子节点对象,没有子节点。实现了抽象构件中定义的行为

容器构件(Composite):表示容器节点对象,包含子节点,其子节点既可以是叶子节点,也可以是容器节点。实现了抽象构件中的行为

 

组合模式通过定义一个抽象构件类,来达到统一处理的效果。因为抽象构件类既可以是叶子,又可以是容器,客户端针对抽象构件类进行编程,所以无须关心它是叶子还是容器。容器对象和抽象构件类形成一个聚合关联关系,容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成树形结构

 

组合模式中,根据抽象构件中有没有声明用于管理成员对象的方法,分为透明组合模式安全组合模式。透明组合模式是组合模式的标椎形式

 

下面代码演示组合模式

透明组合模式(标准组合模式)

定义抽象构件类

package com.design.structural.composite.transparent;

/**
 * 抽象构件
 */
public abstract class Component {

    public abstract void add(Component component);

    public abstract void remove(Component component);

    public abstract void operation();
}

定义叶子构件

package com.design.structural.composite.transparent;

/**
 * 叶子构件
 */
public class Leaf extends Component{

    private String name;

    public Leaf(String name){
        this.name = name;
    }

    @Override
    public void add(Component component) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void remove(Component component) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void operation() {
        System.out.println(name);
    }
}

定义容器构件类

package com.design.structural.composite.transparent;

import java.util.ArrayList;
import java.util.List;

/**
 * 容器构件
 */
public class Composite extends Component{

    private List<Component> list = new ArrayList<Component>();

    private String name;

    private Integer level;

    public Composite(String name, Integer level){
        this.name = name;
        this.level = level;
    }

    @Override
    public void add(Component component) {
        list.add(component);
    }

    @Override
    public void remove(Component component) {
        list.remove(component);
    }

    @Override
    public void operation() {
        System.out.println(this.name);
        for (Component component : list){
            //容器构件级别判断
            if (level != null){
                for (int i=0; i<level; i++){
                    System.out.print(" ");
                }
            }

            component.operation();
        }
    }
}

 

透明组合模式(标椎组合模式)类图如下

通过类图可以看出:透明组合模式在抽象构件 Component 中声明了所有用于管理成员对象的方法,包括 add(Component component)、remove(Component component),这样做确保了所有构件类都有相同的接口

 

测试调用

package com.design.structural.composite.transparent;

/**
 * 组合模式(透明)
 */
public class TestMain {

    public static void main(String[] args) {
        Component leaf1 = new Leaf("叶子1");
        Component leaf2 = new Leaf("叶子2");
        Component leaf3 = new Leaf("叶子3");
        Component leaf4 = new Leaf("叶子4");
        Component leaf5 = new Leaf("叶子5");
        Component leaf6 = new Leaf("叶子6");

        Component composite1 = new Composite("容器构件1", 2);
        Component composite2 = new Composite("容器构件2", 2);

        composite1.add(leaf1);
        composite1.add(leaf2);

        composite2.add(leaf3);
        composite2.add(leaf4);
        composite2.add(leaf5);

        Component composite = new Composite("总容器构件", 1);
        composite.add(composite1);
        composite.add(composite2);
        composite.add(leaf6);

        composite.operation();
    }
}

效果如下图

 

 

安全组合模式

定义抽象构件类

package com.design.structural.composite.security;

/**
 * 抽象构件
 */
public abstract class Component {

    public abstract void operation();
}

定义叶子构件类

package com.design.structural.composite.security;

/**
 * 叶子构件
 */
public class Leaf extends Component{

    private String name;

    public Leaf(String name){
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println(this.name);
    }
}

定义容器构件类

package com.design.structural.composite.security;

import java.util.ArrayList;
import java.util.List;

/**
 * 容器构件
 */
public class Composite extends Component{

    private List<Component> list = new ArrayList<Component>();

    private String name;

    private Integer level;

    public Composite(String name, Integer level) {
        this.name = name;
        this.level = level;
    }

    public void add(Component component){
        list.add(component);
    }

    public void remove(Component component){
        list.remove(component);
    }

    @Override
    public void operation() {
        System.out.println(this.name);
        for (Component component : list){
            if (level != null){
                for (int i=0; i<level; i++){
                    System.out.print(" ");
                }
            }

            component.operation();
        }
    }
}

 

安全组合模式类图如下

通过类图可以看出:安全组合模式在抽象构件 Component 中没有声明任何用于管理成员对象的方法,而是在 Composite 类中声明并实现了这些方法。因此叶子对象不能操作管理成员对象的方法,保证了安全

 

测试调用

package com.design.structural.composite.security;

/**
 * 组合模式(安全)
 */
public class TestMain {

    public static void main(String[] args) {
        Leaf leaf1 = new Leaf("叶子1");
        Leaf leaf2 = new Leaf("叶子2");
        Leaf leaf3 = new Leaf("叶子3");
        Leaf leaf4 = new Leaf("叶子4");
        Leaf leaf5 = new Leaf("叶子5");
        Leaf leaf6 = new Leaf("叶子6");

        Composite composite1 = new Composite("容器构件1", 2);
        Composite composite2 = new Composite("容器构件2", 2);

        composite1.add(leaf1);
        composite1.add(leaf2);

        composite2.add(leaf3);
        composite2.add(leaf4);
        composite2.add(leaf5);

        Composite composite = new Composite("总容器构件", 1);
        composite.add(leaf6);
        composite.add(composite1);
        composite.add(composite2);

        composite.operation();
    }
}

效果如下

 

 

 

组合模式总结

优点:清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得客户端忽略了层次的差异,易于对整个层次结构进行控制;简化客户端代码;符合开闭原则;可以形成复杂的树形结构,且对树形结构的控制非常简单

缺点:对类型进行限制时,会比较复杂;设计变得更加抽象

适用场景:希望客户端可以忽略组合对象和单个对象差异时;系统中需要处理一个树形结构

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世君子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值