设计模式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);
    }
}
    

组合模式代码

相关推荐
UrSpecial9 小时前
设计模式:建造者模式
设计模式·建造者模式
Your易元10 小时前
模式组合应用-组合模式
组合模式
o0向阳而生0o10 小时前
99、23种设计模式之组合模式(8/23)
设计模式·组合模式
爱学习的小熊猫_10 小时前
设计模式之命令模式
设计模式·命令模式
liang_jy1 天前
抽象工厂模式
android·设计模式·面试
liang_jy1 天前
工厂方法模式
android·设计模式·面试
郝学胜-神的一滴1 天前
策略模式:模拟八路军的抗日策略
开发语言·c++·程序人生·设计模式·策略模式
秋难降1 天前
结构型模式 “全家桶”:适配、装饰、代理…7 种模式让你的代码更 “有章法”
java·设计模式·程序员
ytadpole1 天前
揭秘设计模式:从UI按钮到Spring事件的观察者模式
设计模式