Java设计模式之java组合模式详解

Java组合模式详解

什么是组合模式?

组合模式是一种结构型设计模式,其主要思想是将对象组合成树形结构以表示“部分整体”的层次结构。组合模式中包含两种基本的组件:

  1. 叶节点(Leaf): 叶节点代表树的最底层的节点,即无子节点的节点。
  2. 复合节点(Composite): 复合节点代表树的非叶子节点,它可能包含子节点,也可能不包含。

组合模式的优点

  • 可以更方便地扩展对象结构;
  • 对象与对象集合使用起来方便一致;
  • 简化了实现客户端代码的复杂性。

Java组合模式的实现方式

我们可以通过抽象类和接口的方式进行组合模式的实现。以员工管理为例,假设员工管理有以下两种类型的员工:

  • 普通员工(Leaf节点)
  • 经理(Composite节点)

我们可以定义一个抽象类把员工类型进行统一。该类可以是抽象类或者是接口:

abstract class Employee {
    private String name;
    private Department department;

    public Employee(String name, Department department) {
        this.name = name;
        this.department = department;
    }

    public String getName() {
        return name;
    }

    public Department getDepartment() {
        return department;
    }

    // 其他操作
    // ...

    /**
     * 添加员工
     *
     * @param employee 新增员工
     */
    public void add(Employee employee) {
        throw new UnsupportedOperationException("add");
    }

    /**
     * 删除员工
     *
     * @param employee 删除的员工
     */
    public void remove(Employee employee) {
        throw new UnsupportedOperationException("remove");
    }

    /**
     * 打印员工
     *
     * @param depth 打印深度
     */
    public abstract void print(int depth);
}

在抽象类中,我们定义了员工的名称和所属部门属性,并定义了是否是叶子节点方法和添加、删除、打印操作的抽象方法。

在这个抽象类中,并没有实现添加、删除和打印的具体操作,因为普通员工没有子员工,所以这些操作不支持对普通员工的操作。而对于经理节点,因其下面有可能包含一些子员工,因此需要重写这些方法:

class Manager extends Employee {
    private List<Employee> employees = new ArrayList<>();

    public Manager(String name, Department department) {
        super(name, department);
    }

    /**
     * 添加员工
     *
     * @param employee 新增员工
     */
    @Override
    public void add(Employee employee) {
        employees.add(employee);
    }

    /**
     * 删除员工
     *
     * @param employee 删除的员工
     */
    @Override
    public void remove(Employee employee) {
        employees.remove(employee);
    }

    /**
     * 打印员工
     *
     * @param depth 打印深度
     */
    @Override
    public void print(int depth) {
        System.out.println("depth:" + depth + ", name:" + getName());
        for (Employee employee : employees) {
            employee.print(depth + 1);
        }
    }
}

在这个实现中,Manager继承了我们定义的Employee类,并且重写了add、remove和print操作。我们可以发现,其下面定义了员工列表,这个列表中可以添加其他的Employee类型实例,也就是说,Manager可以添加其他的经理和普通员工实例。

由于普通员工没有子员工,因此它可以不重写add、remove和print方法。

组合模式的使用场景

组合模式通常需要满足以下两个条件:

  1. 应用程序需要表示部分和整体层次关系;
  2. 应用程序需要从客户端比较同一组别的对象。

例如:

  • 文件系统的目录和文件;
  • 组织结构图和员工;
  • 菜单、子菜单和菜单项等界面元素。

例子一:组织结构图和员工

我们假设一个公司有多个部门,每个部门中有多个员工,公司最高管理者是CEO。我们可以用组合模式来表达出这些关系。

Department marketing = new Department("Marketing");
Department rd = new Department("Research and Development");
Department finance = new Department("Finance");

Employee ceo = new Manager("William", marketing);
Employee cto = new Manager("Marshall", rd);
Employee cfo = new Manager("Peeters", finance);

ceo.add(cto);
ceo.add(cfo);

Employee staff1 = new Manager("Andy", marketing);
Employee staff2 = new Manager("Simon", marketing);
Employee staff3 = new Manager("Kate", rd);
Employee staff4 = new Manager("Bob", finance);

cto.add(staff1);
cto.add(staff2);
cfo.add(staff3);
cfo.add(staff4);

ceo.print(0);

执行上述代码可以得到如下输出:

depth:0, name:William
depth:1, name:Marshall
depth:2, name:Andy
depth:2, name:Simon
depth:1, name:Peeters
depth:2, name:Kate
depth:2, name:Bob

例子二:煎饼糖果店销售情况

我们假设有一个煎饼糖果店,这家店面积不大,但是它有煎饼、糖果和饮料等多种商品,我们对这些商品进行销售管理。

MenuItem pancake = new MenuItem("Pancake", "A delicious pancake with maple syrup", 2.99);
MenuItem candy = new MenuItem("Candy", "Candy with many flavors", 1.99);
MenuItem drink = new MenuItem("Drink", "Drinks and juices", 0.99);
MenuComponent menu = new Menu("Menu");

menu.add(pancake);
menu.add(candy);
menu.add(drink);

MenuComponent combo = new Menu("Combo");

MenuItem pancakeCombo = new MenuItem("Pancake Combo", "A delicious pancake with maple syrup and coffee or tea", 4.99);
MenuItem candyCombo = new MenuItem("Candy Combo", "Candy with many flavors and coffee or tea", 3.99);

combo.add(pancakeCombo);
combo.add(candyCombo);
combo.add(drink);

menu.add(combo);

menu.print();

执行上述代码可以得到如下输出:

Menu:
    Pancake A delicious pancake with maple syrup    $2.99
    Candy   Candy with many flavors $1.99
    Drink   Drinks and juices   $0.99
    Combo:
        Pancake Combo   A delicious pancake with maple syrup and coffee or tea  $4.99
        Candy Combo Candy with many flavors and coffee or tea   $3.99
        Drink   Drinks and juices   $0.99

总结

组合模式主要用于树形结构的处理,它将对象组织成树形结构,并且能够以同样的方式处理单个对象以及对象集合,从而让客户端用一致性的方式处理对象。组合模式是设计渐进式的设计策略,即它允许我们逐步地将简单的对象组合成更为复杂的对象结构。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之java组合模式详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Eclipse在线安装hibernate插件

    下面是“Eclipse在线安装Hibernate插件”的完整攻略。 安装步骤 打开Eclipse IDE,点击菜单栏上的 Help -> Eclipse Marketplace 进入插件市场。 在搜索框中输入 hibernate,点击搜索按钮,等待搜索结果出现。 选择需要安装的 Hibernate Tools 插件,点击右侧的 Install 按钮,进…

    Java 2023年5月20日
    00
  • springdata jpa单表操作crud的实例代码详解

    下面我将为您详细讲解“springdata jpa单表操作crud的实例代码详解”的完整攻略。 一、前言 Spring Data JPA是Spring Data中一个很重要的模块,可以方便地进行关系型数据库的访问和操作。在本篇攻略中,我们将详细讲解如何使用Spring Data JPA进行单表操作CRUD。 二、准备工作 在使用Spring Data JPA…

    Java 2023年5月20日
    00
  • mybatis自动建表的实现方法

    MyBatis是一个流行的ORM框架,可以让开发人员通过简单的配置实现Java对象与关系型数据库之间的映射。它支持自动建表,在配置文件中添加一些参数,就可以让MyBatis自动创建数据库表结构。下面是实现自动建表的步骤: 1. 添加自动建表所需的依赖 在pom.xml文件中添加如下依赖: <dependency> <groupId>o…

    Java 2023年5月20日
    00
  • Java中的JUnit是什么?

    JUnit是Java中最受欢迎的测试框架之一,用于编写单元测试。在软件开发中,单元测试是用于测试小部分代码的实践,以确保它们能够按照预期进行工作,同时也是保证代码质量和可维护性的重要步骤。在本文中,我们将详细讲解JUnit的各个方面,从安装到使用。 安装 JUnit可以通过Maven在Java项目中安装,只需要在项目的pom.xml文件中添加以下依赖项即可:…

    Java 2023年4月27日
    00
  • Mybatis的Dao层实现原理分析

    接下来我将详细讲解Mybatis的Dao层实现原理分析的完整攻略。 什么是Dao层 Dao层是指数据访问层,它负责与数据库进行交互,完成数据的增、删、改、查等操作。在Dao层中,最常用的是SQL语句。Mybatis是一种主流的持久层框架,它的Dao层实现原理值得深入学习。 Mybatis的Dao层实现原理 1. 配置文件 Mybatis框架使用XML文件来配…

    Java 2023年5月20日
    00
  • Java中使用Properties配置文件的简单方法

    下面是详细的Java中使用Properties配置文件的攻略。 1. Properties配置文件介绍 Properties类是Java提供的一个工具类,可以方便地读取和写入配置文件。使用Properties可以将配置信息保存在文件中,比如常见的应用程序的配置信息。Properties文件是一种常见的配置文件格式,可以用键值对(key=value)的方式保存…

    Java 2023年5月20日
    00
  • Spring Security权限管理小结

    关于“Spring Security权限管理小结”的完整攻略,我们可以从以下几个方面来介绍。 1. Spring Security简介 Spring Security是一款基于Spring框架的安全框架,提供了丰富的安全特性和机制,支持登录认证、授权访问、安全协议、攻击防护等功能。在Spring应用中,使用Spring Security可以非常方便地实现系统…

    Java 2023年5月19日
    00
  • Hibernate延迟加载原理与实现方法

    下面是对于Hibernate延迟加载原理与实现方法的详细讲解。 1. Hibernate延迟加载的原理 Hibernate提供了延迟加载(Lazy Loading)的机制,延迟加载指的是在运行时如果检测到某个属性没有被访问,那么Hibernate就不会去加载该属性对应的数据库记录,直到在程序中第一次访问该属性时再去加载。 延迟加载的实现是Hibernate对…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部