当前位置: 首页 > news >正文

组合模式

文章目录

    • 思考组合模式
      • 1.组合模式的本质
      • 2.何时选用组合模式
      • 3.优缺点
      • 4.实现

思考组合模式

组合模式实际上就是让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。

1.组合模式的本质

组合模式的本质:统一叶子对象和组合对象。

组合模式通过把叶子对象当成特殊的组合对象看待,从而对叶子对象和组合对象一视同仁,全部当成了Component对象,有机地统一了叶子对象和组合对象。
正是因为统一了叶子对象和组合对象,在将对象构建成树型结构的时候,才不需要做区分,反正是组件对象里面包含其他的组件对象,如此递归下去;也才使得对于树形结构的操作变得简单,不管对象类型,统一操作。
在这里插入图片描述

  • Component:抽象的组件对象,为组合中的对象声明接口,让客户端可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的功能提供缺省的实现。
  • Leaf:叶子节点对象,定义和实现叶子对象的行为,不再包含其他的子节点对象。
  • Composite:组合对象,通常会存储子组件,定义包含子组件的那些组件的行为,并实现在组件接口中定义的与子组件有关的操作。
  • Client:客户端,通过组件接口来操作组合结构里面的组件对象。

2.何时选用组合模式

建议在以下情况中选用组合模式。

  • 如果你想表示对象的部分—整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用这个层次结构也容易。
  • 如果你希望统一地使用组合结构中的所有对象,可以选用组合模式,这正是组合模式提供的主要功能。

3.优缺点

组合模式有以下优点。

  • 定义了包含基本对象和组合对象的类层次结构
    在组合模式中,基本对象可以被组合成复杂的组合对象,而组合对象又可以组合成更复杂的组合对象,可以不断地递归组合下去,从而构成一个统一的组合对象的类层次结构。

  • 统一了组合对象和叶子对象
    在组合模式中,可以把叶子对象当作特殊的组合对象看待,为它们定义统一的父类,从而把组合对象和叶子对象的行为统一起来。

  • 简化了客户端调用
    组合模式通过统一组合对象和叶子对象,使得客户端在使用它们的时候,不需要再去区分它们,客户不关心使用的到底是什么类型的对象,这就大大简化了客户端的使用。

  • 更容易扩展
    由于客户端是统一地面对Component来操作,因此,新定义的Composite或 Leaf子类能够很容易地与已有的结构一起工作,而客户端不需要为增添了新的组件类而改变。

4.实现

一个学校有多个学院,一个学院有多个专业,抽象成一个树形结构
学校和学院都可以有叶子节点,可以共用一个类(Composite),叶子节点单独用一个类(Leaf)
在这里插入图片描述

1.父接口

/**
 * @description:父接口
 */
@Data
public abstract class Component {

    /**
     * 打印
     * @param preStr
     */
    public abstract void print(String preStr);

    /**
     * 添加对象
     * @param component
     */
    public void add(Component component){
        throw new UnsupportedOperationException("对象不支持这个功能");
    }

    /**
     * 移除对象
     * @param component
     */
    public void remove(Component component){
        throw new UnsupportedOperationException("对象不支持这个功能");
    }

}

2.组合对象类

/**
 * @description:组合对象(学校、学院)
 */
public class Composite extends Component {

    private String name;

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

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

    @Override
    public void print(String preStr) {
        System.out.println(preStr+"+"+this.name);
        if (this.list!=null){
            preStr+=" ";
            for (Component c: list){
                c.print(preStr);
            }
        }
    }

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

}

3.叶子类

/**
 * @description:叶子对象(系)
 */
@AllArgsConstructor
public class Leaf extends Component {

    /**
     * 叶子节点名字
     */
    private String name;

    @Override
    public void print(String preStr) {
        System.out.println(preStr+"-"+name);
    }
}

4.测试类

public class Client {


    public static void main(String[] args) {
        //学校
        Component university = new Composite("清华大学");
        //学院
        Component computerCollege = new Composite("计算机学院");
        Component mathCollege = new Composite("数学学院");

        //学院添加系
        computerCollege.add(new Leaf("软件"));
        computerCollege.add(new Leaf("电子"));
        computerCollege.add(new Leaf("通信"));
        mathCollege.add(new Leaf("概率"));
        mathCollege.add(new Leaf("统计"));

        //学校添加学院
        university.add(computerCollege);
        university.add(mathCollege);

        //输出学校结构
        university.print("");
    }
}

在这里插入图片描述
这样就实现了类似树形结构
在这里插入图片描述

相关文章:

  • flash个人网站源码/软文网站推广法
  • 沧州手机网站/seo站长常用工具
  • wordpress企业模板免费下载/如何写营销软文
  • 零基础网站建设/百度问答首页
  • wordpress 伪静态 中文/b站引流推广
  • 网站建设ASP心得体会/河南网站优化公司哪家好
  • 第四次考核 Jimmy 学徒考核 Linux安装软件 rnaseq上游分析
  • HTML + CSS + 小程序+js教程
  • ROS action客户端和服务端通信(Ubuntu )
  • [附源码]计算机毕业设计网上鲜花购物系统Springboot程序
  • SpringBoot+Vue项目便捷洗衣服务平台
  • 网格化微型空气质量站 浅谈工作原理
  • uImage的制作工具mkimage详解(源码编译、使用方法、添加的头解析、uImage的制作)
  • Windows OpenGL ES 图像绿幕抠图
  • 给出32位有符号整数,将这个整数翻转
  • Numpy入门[11]——生成数组的函数
  • 【MyBatis源码分析】四、XML解析与核心对象的构建
  • WEB前端网页设计 HTML网页代码 基础参数(二)