编程自学指南:java程序设计开发,Java 组合模式(Composite),组合模式的概念和核心思想,组合模式的结构和各个角色的作用,使用组合模式构建树形结构的对象

编程自学指南:java程序设计开发,Java 组合模式(Composite)

一、课程信息

学习目标

  1. 理解组合模式的概念和核心思想。
  2. 掌握组合模式的结构和各个角色的作用。
  3. 学会使用组合模式构建树形结构的对象。
  4. 能够识别并应用组合模式解决实际开发中的问题。

二、课程导入

生活实例引入

  • 以文件系统为例,文件系统中存在文件和文件夹。文件夹可以包含文件,也可以包含其他文件夹,形成了一种树形结构。当我们对文件夹进行操作(如复制、删除)时,实际上是对其包含的所有文件和子文件夹进行相同的操作。
  • 提问学生生活中还有哪些类似的树形结构例子,引导他们思考如何用编程来处理这种结构。

三、组合模式的基本概念

定义

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示 “部分 - 整体” 的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。

核心思想

将对象组合成树形结构,以表示 “部分 - 整体” 的层次关系,并且可以统一处理单个对象和组合对象。

组合模式的好处

  • 可以方便地处理树形结构,对单个对象和组合对象的操作具有一致性。
  • 提高了系统的可扩展性,方便添加新的对象类型。

四、组合模式的结构和角色

结构

组合模式主要由以下三个角色组成:

  1. 抽象构件(Component):定义了叶子构件和容器构件的共同接口,声明了客户端调用的基本操作。
  2. 叶子构件(Leaf):表示树形结构中的叶子节点,没有子节点,实现了抽象构件中定义的基本操作。
  3. 容器构件(Composite):表示树形结构中的容器节点,包含子节点,可以是叶子节点或其他容器节点。容器构件实现了抽象构件中定义的操作,并且可以管理其子节点。

角色关系图

可以使用简单的 UML 图展示三个角色之间的关系,帮助学生理解。

示例代码结构

// 抽象构件
abstract class Component {
    protected String name;

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

    public abstract void operation();

    public void add(Component component) {
        throw new UnsupportedOperationException();
    }

    public void remove(Component component) {
        throw new UnsupportedOperationException();
    }

    public Component getChild(int index) {
        throw new UnsupportedOperationException();
    }
}

// 叶子构件
class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void operation() {
        System.out.println("叶子构件 " + name + " 执行操作");
    }
}

// 容器构件
class Composite extends Component {
    private java.util.ArrayList<Component> children = new java.util.ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void operation() {
        System.out.println("容器构件 " + name + " 执行操作");
        for (Component child : children) {
            child.operation();
        }
    }

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

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

    @Override
    public Component getChild(int index) {
        return children.get(index);
    }
}

代码解释

  • Component 是抽象构件,定义了所有构件的共同接口,包括 operation() 方法用于执行操作,以及 add()remove() 和 getChild() 方法用于管理子节点。默认情况下,这些方法抛出 UnsupportedOperationException,表示叶子节点不支持这些操作。
  • Leaf 是叶子构件,继承自 Component,实现了 operation() 方法,用于执行叶子节点的操作。
  • Composite 是容器构件,继承自 Component,包含一个 ArrayList 用于存储子节点。实现了 operation() 方法,会递归调用所有子节点的 operation() 方法。同时实现了 add()remove() 和 getChild() 方法,用于管理子节点。

五、实际案例分析

案例一:公司组织架构

// 抽象构件:员工
abstract class Employee {
    protected String name;

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

    public abstract void showInfo();

    public void add(Employee employee) {
        throw new UnsupportedOperationException();
    }

    public void remove(Employee employee) {
        throw new UnsupportedOperationException();
    }

    public Employee getChild(int index) {
        throw new UnsupportedOperationException();
    }
}

// 叶子构件:普通员工
class RegularEmployee extends Employee {
    public RegularEmployee(String name) {
        super(name);
    }

    @Override
    public void showInfo() {
        System.out.println("普通员工:" + name);
    }
}

// 容器构件:部门经理
class DepartmentManager extends Employee {
    private java.util.ArrayList<Employee> subordinates = new java.util.ArrayList<>();

    public DepartmentManager(String name) {
        super(name);
    }

    @Override
    public void showInfo() {
        System.out.println("部门经理:" + name);
        for (Employee subordinate : subordinates) {
            subordinate.showInfo();
        }
    }

    @Override
    public void add(Employee employee) {
        subordinates.add(employee);
    }

    @Override
    public void remove(Employee employee) {
        subordinates.remove(employee);
    }

    @Override
    public Employee getChild(int index) {
        return subordinates.get(index);
    }
}

// 测试代码
public class CompanyOrganizationDemo {
    public static void main(String[] args) {
        // 创建部门经理
        DepartmentManager manager = new DepartmentManager("张经理");

        // 创建普通员工
        RegularEmployee employee1 = new RegularEmployee("小李");
        RegularEmployee employee2 = new RegularEmployee("小王");

        // 将普通员工添加到部门经理的下属列表中
        manager.add(employee1);
        manager.add(employee2);

        // 显示部门信息
        manager.showInfo();
    }
}

代码解释

  • Employee 是抽象构件,定义了员工的基本操作,包括 showInfo() 方法用于显示员工信息,以及 add()remove() 和 getChild() 方法用于管理下属。
  • RegularEmployee 是叶子构件,继承自 Employee,实现了 showInfo() 方法,用于显示普通员工的信息。
  • DepartmentManager 是容器构件,继承自 Employee,包含一个 ArrayList 用于存储下属员工。实现了 showInfo() 方法,会递归调用所有下属员工的 showInfo() 方法。同时实现了 add()remove() 和 getChild() 方法,用于管理下属员工。

案例二:菜单系统

// 抽象构件:菜单项
abstract class MenuComponent {
    protected String name;

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

    public abstract void print();

    public void add(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }

    public void remove(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }

    public MenuComponent getChild(int index) {
        throw new UnsupportedOperationException();
    }
}

// 叶子构件:具体菜单项
class MenuItem extends MenuComponent {
    public MenuItem(String name) {
        super(name);
    }

    @Override
    public void print() {
        System.out.println("菜单项:" + name);
    }
}

// 容器构件:菜单
class Menu extends MenuComponent {
    private java.util.ArrayList<MenuComponent> menuComponents = new java.util.ArrayList<>();

    public Menu(String name) {
        super(name);
    }

    @Override
    public void print() {
        System.out.println("菜单:" + name);
        for (MenuComponent menuComponent : menuComponents) {
            menuComponent.print();
        }
    }

    @Override
    public void add(MenuComponent menuComponent) {
        menuComponents.add(menuComponent);
    }

    @Override
    public void remove(MenuComponent menuComponent) {
        menuComponents.remove(menuComponent);
    }

    @Override
    public MenuComponent getChild(int index) {
        return menuComponents.get(index);
    }
}

// 测试代码
public class MenuSystemDemo {
    public static void main(String[] args) {
        // 创建主菜单
        Menu mainMenu = new Menu("主菜单");

        // 创建子菜单
        Menu subMenu = new Menu("子菜单");

        // 创建具体菜单项
        MenuItem item1 = new MenuItem("菜单项 1");
        MenuItem item2 = new MenuItem("菜单项 2");
        MenuItem item3 = new MenuItem("菜单项 3");

        // 将菜单项添加到子菜单中
        subMenu.add(item1);
        subMenu.add(item2);

        // 将子菜单和菜单项添加到主菜单中
        mainMenu.add(subMenu);
        mainMenu.add(item3);

        // 打印主菜单
        mainMenu.print();
    }
}

代码解释

  • MenuComponent 是抽象构件,定义了菜单项的基本操作,包括 print() 方法用于打印菜单项信息,以及 add()remove() 和 getChild() 方法用于管理子菜单项。
  • MenuItem 是叶子构件,继承自 MenuComponent,实现了 print() 方法,用于打印具体菜单项的信息。
  • Menu 是容器构件,继承自 MenuComponent,包含一个 ArrayList 用于存储子菜单项。实现了 print() 方法,会递归调用所有子菜单项的 print() 方法。同时实现了 add()remove() 和 getChild() 方法,用于管理子菜单项。

六、组合模式的优缺点和适用场景

优点

  • 可以方便地处理树形结构,对单个对象和组合对象的操作具有一致性。
  • 提高了系统的可扩展性,方便添加新的对象类型。
  • 符合开闭原则,对扩展开放,对修改关闭。

缺点

  • 可能会导致设计变得复杂,尤其是在处理复杂的树形结构时。
  • 很难限制容器构件中可以包含的叶子构件类型。

适用场景

  • 当需要表示一个 “部分 - 整体” 的层次结构,并且希望统一处理单个对象和组合对象时,可以使用组合模式。
  • 当需要忽略单个对象和组合对象的差异,统一使用它们时,可以使用组合模式。

七、课堂练习

练习一

  • 设计一个组合模式的示例,模拟学校的组织架构。学校包含多个学院,每个学院包含多个专业,每个专业包含多个班级。

练习二

  • 扩展菜单系统案例,增加一个新的菜单和一些新的菜单项,并测试代码。

八、课程总结

知识回顾

  • 回顾组合模式的概念、核心思想和结构。
  • 总结组合模式的优缺点和适用场景。
  • 强调组合模式在处理树形结构中的重要性。

常见问题解答

  • 解答学生在课堂练习和学习过程中遇到的问题。

口诀总结

  • “组合模式很奇妙,树形结构它来搞。部分整体成层次,操作一致真有效。容器叶子共抽象,递归调用少不了。扩展方便结构妙,复杂设计要知晓。”

九、课后作业

作业一

  • 设计一个组合模式的示例,模拟电商系统中的商品分类。商品分类可以包含子分类和具体商品。

作业二

  • 思考在实际项目中,还有哪些场景可以使用组合模式来优化代码结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zl515035644

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值