组合模式(十二)

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

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

一. 组合模式

引用 菜鸟教程里面的 组合 模式介绍: 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、节点自由增加。

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

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

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

组成角色具体关系作用
ComponentOrgComponent用于访问和管理 Component 子部件用于访问和管理 Component 子部件
LeafZhuanYe叶子节点,没有子节点叶子节点,没有子节点
CompositeDaXue, XueYuan非叶子节点,用于存储子部件非叶子节点,用于存储子部件

image-20230614171304909

二. 组合模式实例

  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();


    }

image-20230614171849926

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

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


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


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


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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

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

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

打赏作者

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

抵扣说明:

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

余额充值