设计模式14-组合模式

定义

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

场景

  • 处理树形结构数据:如文件系统(文件和文件夹)、组织架构(部门和员工)、菜单系统(菜单项和子菜单)等。

  • 需要统一操作单个对象和组合对象:当客户端代码需要对「单个元素」和「元素集合」执行相同操作时(如计算总大小、展示信息等)。

  • 动态构建层次结构:需要灵活地增加 / 删除层级节点,且不影响客户端对结构的使用。

代码

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 组合节点:复合部门(可以包含子部门)
public class CompositeDepartment implements DepartmentComponent {
    private String name;
    private List<DepartmentComponent> children = new ArrayList<>();

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

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

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

    @Override
    public void display(int depth) {
        // 显示部门信息,并递归显示所有子部门
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("  ");
        }
        sb.append("+ ").append(name).append(" (总员工数: ").append(getEmployeeCount()).append(")");
        System.out.println(sb.toString());

        // 递归显示子部门
        for (DepartmentComponent child : children) {
            child.display(depth + 1);
        }
    }

    @Override
    public int getEmployeeCount() {
        // 计算本部门总员工数(所有子部门员工数之和)
        int total = 0;
        for (DepartmentComponent child : children) {
            total += child.getEmployeeCount();
        }
        return total;
    }

    @Override
    public String getName() {
        return name;
    }
}

// 部门组件接口:定义所有部门组件的共同行为
interface DepartmentComponent {
    // 添加子部门
    void add(DepartmentComponent component);

    // 移除子部门
    void remove(DepartmentComponent component);

    // 显示部门信息
    void display(int depth);

    // 获取部门员工数量
    int getEmployeeCount();

    // 获取部门名称
    String getName();
}

// 叶子节点:基础部门(不能包含子部门)
class LeafDepartment implements DepartmentComponent {
    private String name;
    private int employeeCount;

    public LeafDepartment(String name, int employeeCount) {
        this.name = name;
        this.employeeCount = employeeCount;
    }

    @Override
    public void add(DepartmentComponent component) {
        // 叶子节点不能添加子部门
        throw new UnsupportedOperationException("基础部门不能包含子部门");
    }

    @Override
    public void remove(DepartmentComponent component) {
        // 叶子节点没有子部门可移除
        throw new UnsupportedOperationException("基础部门没有子部门可移除");
    }

    @Override
    public void display(int depth) {
        // 显示部门信息,使用depth控制缩进
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("  ");
        }
        sb.append("- ").append(name).append(" (员工数: ").append(employeeCount).append(")");
        System.out.println(sb.toString());
    }

    @Override
    public int getEmployeeCount() {
        return employeeCount;
    }

    @Override
    public String getName() {
        return name;
    }
}

// 演示部门树形结构的使用
class DepartmentHierarchyDemo {
    public static void main(String[] args) {
        // 创建公司顶级部门
        CompositeDepartment company = new CompositeDepartment("总公司");

        // 创建一级部门
        CompositeDepartment techDepartment = new CompositeDepartment("技术部");
        CompositeDepartment marketingDepartment = new CompositeDepartment("市场部");
        CompositeDepartment adminDepartment = new CompositeDepartment("行政部");

        // 向技术部添加二级部门
        techDepartment.add(new LeafDepartment("前端开发组", 12));
        techDepartment.add(new LeafDepartment("后端开发组", 18));

        // 创建三级部门结构
        CompositeDepartment productDepartment = new CompositeDepartment("产品研发中心");
        productDepartment.add(new LeafDepartment("产品设计组", 5));
        productDepartment.add(new LeafDepartment("测试组", 8));
        productDepartment.add(new LeafDepartment("运维组", 6));

        // 将产品研发中心添加到技术部(成为二级部门)
        techDepartment.add(productDepartment);

        // 向市场部添加二级部门
        marketingDepartment.add(new LeafDepartment("市场推广组", 6));
        marketingDepartment.add(new LeafDepartment("销售组", 20));

        // 向行政部添加二级部门
        adminDepartment.add(new LeafDepartment("人力资源组", 4));
        adminDepartment.add(new LeafDepartment("财务组", 5));
        adminDepartment.add(new LeafDepartment("行政后勤组", 3));

        // 将一级部门添加到公司
        company.add(techDepartment);
        company.add(marketingDepartment);
        company.add(adminDepartment);

        // 展示整个部门层级结构
        System.out.println("公司部门层级结构:");
        company.display(0);
    }
}
    

组合模式代码

相关推荐
Asort4 小时前
JavaScript设计模式(十四)——命令模式:解耦请求发送者与接收者
前端·javascript·设计模式
秉承初心4 小时前
Java 23种设计模式的详细解析
java·设计模式
TsengOnce5 小时前
设计模式(解释器模式(Interpreter Pattern)结构|原理|优缺点|场景|示例
设计模式·解释器模式
猫头虎7 小时前
OpenAI发布构建AI智能体的实践指南:实用框架、设计模式与最佳实践解析
人工智能·设计模式·开源·aigc·交互·pip·ai-native
昨天的猫7 小时前
项目中原来策略模式这么玩才有意思😁😁😁
设计模式
Mr_WangAndy7 小时前
C++设计模式_行为型模式_迭代器模式Iterator
c++·设计模式·迭代器模式
白衣鸽子7 小时前
【基础数据篇】数据遍历大师:Iterator模式
后端·设计模式
muxin-始终如一7 小时前
系统重构过程以及具体方法
设计模式·重构
Mr_WangAndy20 小时前
C++设计模式_行为型模式_责任链模式Chain of Responsibility
c++·设计模式·责任链模式·行为型模式
星空寻流年20 小时前
设计模式第七章(责任链模式)
设计模式·责任链模式