13-设计模式-组合模式

组合模式概念

以下摘自菜鸟教程

意图:将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

何时使用:
1、您想表示对象的部分-整体层次结构(树形结构)。
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

应用实例:
1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。
2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

优点:
1、高层模块调用简单。
2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项:定义时为具体类。

组合模式主要突出两个关键字:树形结构、整体-部分
接下来先看一个案例

案例

已知,电脑中文件与文件夹。父文件夹中可以存在子文件和子文件夹,子文件夹中又可以存在其子文件夹的子文件和子文件夹。

Component(抽象构件)

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

public interface Component {

    /**
     * 添加组件
     * @return void
     * @param component
     * 时间:2018年4月27日
     */
    void add(Component component); 

    /**
     * 移除组件
     * @return void
     * @param component
     * 时间:2018年4月27日
     */
    void remove(Component component);

    /**
     * 获取组件
     * @return Component
     * @param i
     * @return
     * 时间:2018年4月27日
     */
    Component getCom(int i);

    /**
     * 需要执行的方法
     * @return void
     * 时间:2018年4月27日
     */
    void operation();

}

Leaf(叶子构件)

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

public class CFile implements Component{

    private String name; 

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

    @Override
    public void add(Component component) {
        System.out.println("error");
    }

    @Override
    public void remove(Component component) {
        System.out.println("error");
    }

    @Override
    public Component getCom(int i) {
        System.out.println("error");
        return null;
    }

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

}

Composite(容器构件)

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

public class CFolder implements Component{

    private String name;

    private List<Component> list;

    public CFolder(String name) {
        this.name = name;
        list = new ArrayList<>();
    }

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

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

    @Override
    public Component getCom(int i) {
        return list.get(i);
    }

    @Override
    public void operation() {
        System.out.println(name);
        System.out.println("打开了:" + name);
        for (Component component : list) {
            component.operation();
        }
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        Component component1 = new CFile("A");
        Component component2 = new CFile("B");
        Component component3 = new CFile("C");
        Component component4 = new CFile("D");
        Component component5 = new CFolder("1");
        Component component6 = new CFolder("2");
        Component component7 = new CFolder("3");

        component5.add(component1);
        component5.add(component2);
        component5.add(component6);

        component6.add(component3);
        component6.add(component7);

        component7.add(component4);

        component5.operation();
    }
}

本文参考

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

猜你喜欢

转载自blog.csdn.net/qq_34229789/article/details/80107663