组合模式(十二)

请相信自己,请再次相信自己,请一定要相信自己

上一章简单介绍了装饰者模式(十一), 如果没有看过, 请观看上一章

一. 组合模式

引用 菜鸟教程里面的 组合 模式介绍: https://www.runoob.com/design-pattern/composite-pattern.html

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。

组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,

它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

一.一 介绍

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

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

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

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

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

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

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

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

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

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

组成角色 具体 关系 作用
Component OrgComponent 用于访问和管理 Component 子部件 用于访问和管理 Component 子部件
Leaf ZhuanYe 叶子节点,没有子节点 叶子节点,没有子节点
Composite DaXue, XueYuan 非叶子节点,用于存储子部件 非叶子节点,用于存储子部件

组合模式(十二)_第1张图片

二. 组合模式实例

  1. 定义一个 抽象类, 填入基本的属性和方法

  2. 针对抽象类进行实现, 有叶子节点实现 和 非叶子节点实现

叶子节点实现的话, 没有集合的操作

非叶子节点实现的话, 是有集合引用的, 需要针对集合中的每一个操作进行处理。

二.一 定义子元素

@Data
public abstract class OrgComponent {
    private String name;
    private String desc;


    public OrgComponent (String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public void add (OrgComponent orgComponent) {
        throw new UnsupportedOperationException();
    }
    public void remove(OrgComponent orgComponent) {
        throw new UnsupportedOperationException();
    }

    public OrgComponent getChild(int i) {return null;}

    public abstract void print();

}

二.二 叶子节点

@Slf4j
public class ZhuanYe  extends OrgComponent{

    public ZhuanYe(String name, String desc) {
        super(name, desc);
    }

    @Override
    public void print() {
        log.info(">>>>>>>>>>>>>>>>>>>>>>{}",getName());
    }
}

二.三 非叶子节点

二.三.一 大学

@Slf4j
public class DaXue extends OrgComponent{

    private List<OrgComponent> children = new ArrayList<>();

    public DaXue(String name, String desc) {
        super(name, desc);
    }


    @Override
    public void add(OrgComponent orgComponent) {
        children.add(orgComponent);
    }

    @Override
    public void remove(OrgComponent orgComponent) {
        Iterator<OrgComponent> iterator = children.iterator();
        while(iterator.hasNext()) {
            OrgComponent next = iterator.next();
            if (next.getName().equals(orgComponent.getName())) {
                iterator.remove();
            }
        }
    }

    @Override
    public OrgComponent getChild(int i) {
        if (children.size() > i) {
            return children.get(i);
        }else {
            return null;
        }
    }

    @Override
    public void print() {
       if (!CollectionUtil.isEmpty(children)){
           log.info(">{}",getName());
           for (OrgComponent orgComponent : children) {
               orgComponent.print();
           }
       }
    }
}

二.三.二 学院

@Slf4j
public class XueYuan extends OrgComponent{

    private List<OrgComponent> children = new ArrayList<>();

    public XueYuan(String name, String desc) {
        super(name, desc);
    }


    @Override
    public void add(OrgComponent orgComponent) {
        children.add(orgComponent);
    }

    @Override
    public void remove(OrgComponent orgComponent) {
        Iterator<OrgComponent> iterator = children.iterator();
        while(iterator.hasNext()) {
            OrgComponent next = iterator.next();
            if (next.getName().equals(orgComponent.getName())) {
                iterator.remove();
            }
        }
    }
    @Override
    public OrgComponent getChild(int i) {
        if (children.size() > i) {
            return children.get(i);
        }else {
            return null;
        }
    }
    @Override
    public void print() {
       if (!CollectionUtil.isEmpty(children)){
           log.info(">>>>>>>>>>>{}",getName());
           for (OrgComponent orgComponent : children) {
               orgComponent.print();
           }
       }
    }
}

二.四 测试方法

@Test
    public void oneTest() {
        OrgComponent daXue = new DaXue("大学","大学1");

        OrgComponent xueYuan1 = new XueYuan("学院1","学院1");
        OrgComponent xueYuan2 = new XueYuan("学院2","学院2");

        daXue.add(xueYuan1);
        daXue.add(xueYuan2);

        // 添加专业

        OrgComponent zhuanYe1 = new ZhuanYe("专业1","专业1");
        OrgComponent zhuanYe2 = new ZhuanYe("专业2","专业2");
        OrgComponent zhuanYe3 = new ZhuanYe("专业3","专业3");
        OrgComponent zhuanYe4 = new ZhuanYe("专业4","专业4");


        xueYuan1.add(zhuanYe1);
        xueYuan1.add(zhuanYe2);
        xueYuan2.add(zhuanYe3);
        xueYuan2.add(zhuanYe4);

        log.info(">>>>> 移除之前 大学打印: ");
        // 进行打印
        daXue.print();
        log.info(">>>>> 移除之前 学院打印: ");
        xueYuan1.print();

        xueYuan1.remove( zhuanYe1);

        log.info(">>>>> 移除之后打印: ");

        daXue.print();
        xueYuan1.print();


    }

组合模式(十二)_第2张图片

需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式

要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式


本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Composite


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

你可能感兴趣的:(设计模式,组合模式,设计模式)