设计模式-组合模式

什么是组合模式?

组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次关系。组合模式使得客户端对单个对象和组合对象的使用具有一致性。
组合模式包含以下角色:

  • 组件(Component):声明组合中对象的接口,适当情况下实现所有类共有接口的默认行为
  • 叶子(Leaf):表示叶子节点对象,没有子节点
  • 复合节点(Composite):定义有子部件的部件行为,存储子部件,并在Component接口中实现与子部件有关的操作
  • 客户端(Client):通过Component接口操作组合部件的对象

组合模式的优缺点

优点:

  • 统一处理:客户端可以一致地使用组合结构和单个对象
  • 灵活性:容易增加新的组件类型,符合开闭原则
  • 简化客户端代码:客户端不需要区分叶子节点和组合节点
  • 层次结构清晰:能够清晰地表示对象之间的层次关系

缺点:

  • 设计复杂:系统中存在大量小对象,系统更复杂
  • 难以限制容器中的构件:很难限制组合中的构件类型
  • 不易控制构件类型:不容易用继承的方法来增加新的行为

什么场景下使组合模式

  1. 表示对象的部分-整体层次结构
  2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
  3. 需要遍历组织机构树、文件系统、菜单系统等树形结构
  4. 需要动态地组合对象,形成复杂的层次结构

代码举例

下面是以组织架构为例子

// 组件接口 - 员工组件
abstract class EmployeeComponent {
    protected String name;
    protected String position;
    
    public EmployeeComponent(String name, String position) {
        this.name = name;
        this.position = position;
    }
    
    public String getName() {
        return name;
    }
    
    public String getPosition() {
        return position;
    }
    
    // 抽象方法
    public abstract void display(int depth);
    public abstract double getSalary();
    public abstract int getEmployeeCount();
    public abstract double getTotalSalary();
    
    // 默认实现
    public boolean add(EmployeeComponent employee) {
        throw new UnsupportedOperationException("不支持添加员工");
    }
    
    public boolean remove(EmployeeComponent employee) {
        throw new UnsupportedOperationException("不支持删除员工");
    }
    
    public List<EmployeeComponent> getSubordinates() {
        throw new UnsupportedOperationException("不支持获取下属");
    }
}

// 叶子节点 - 普通员工
class Employee extends EmployeeComponent {
    private double salary;
    
    public Employee(String name, String position, double salary) {
        super(name, position);
        this.salary = salary;
    }
    
    @Override
    public void display(int depth) {
        String indent = "  ".repeat(depth);
        System.out.println(indent + "👤 " + name + " - " + position + " (薪资: ¥" + salary + ")");
    }
    
    @Override
    public double getSalary() {
        return salary;
    }
    
    @Override
    public int getEmployeeCount() {
        return 1;
    }
    
    @Override
    public double getTotalSalary() {
        return salary;
    }
}

// 复合节点 - 管理者
class Manager extends EmployeeComponent {
    private double baseSalary;
    private List<EmployeeComponent> subordinates = new ArrayList<>();
    
    public Manager(String name, String position, double baseSalary) {
        super(name, position);
        this.baseSalary = baseSalary;
    }
    
    @Override
    public boolean add(EmployeeComponent employee) {
        return subordinates.add(employee);
    }
    
    @Override
    public boolean remove(EmployeeComponent employee) {
        return subordinates.remove(employee);
    }
    
    @Override
    public List<EmployeeComponent> getSubordinates() {
        return new ArrayList<>(subordinates);
    }
    
    @Override
    public void display(int depth) {
        String indent = "  ".repeat(depth);
        System.out.println(indent + "💼 " + name + " - " + position + 
                          " (基本薪资: ¥" + baseSalary + ", 下属: " + subordinates.size() + "人)");
        
        for (EmployeeComponent subordinate : subordinates) {
            subordinate.display(depth + 1);
        }
    }
    
    @Override
    public double getSalary() {
        return baseSalary;
    }
    
    @Override
    public int getEmployeeCount() {
        int count = 1; // 包括自己
        for (EmployeeComponent subordinate : subordinates) {
            count += subordinate.getEmployeeCount();
        }
        return count;
    }
    
    @Override
    public double getTotalSalary() {
        double total = baseSalary;
        for (EmployeeComponent subordinate : subordinates) {
            total += subordinate.getTotalSalary();
        }
        return total;
    }
    
    // 获取特定职位的员工
    public List<EmployeeComponent> getEmployeesByPosition(String position) {
        List<EmployeeComponent> result = new ArrayList<>();
        collectEmployeesByPosition(position, result);
        return result;
    }
    
    private void collectEmployeesByPosition(String targetPosition, List<EmployeeComponent> result) {
        if (this.position.equals(targetPosition)) {
            result.add(this);
        }
        
        for (EmployeeComponent subordinate : subordinates) {
            if (subordinate.getPosition().equals(targetPosition)) {
                result.add(subordinate);
            }
            
            if (subordinate instanceof Manager) {
                ((Manager) subordinate).collectEmployeesByPosition(targetPosition, result);
            }
        }
    }
}

// 客户端使用示例
public class OrganizationDemo {
    public static void main(String[] args) {
        // 创建CEO
        Manager ceo = new Manager("张三", "CEO", 100000);
        
        // 创建部门经理
        Manager cto = new Manager("李四", "CTO", 80000);
        Manager cfo = new Manager("王五", "CFO", 75000);
        Manager hrManager = new Manager("赵六", "HR经理", 60000);
        
        // 创建技术团队
        Manager techManager = new Manager("钱七", "技术经理", 50000);
        Employee developer1 = new Employee("孙八", "高级开发工程师", 35000);
        Employee developer2 = new Employee("周九", "中级开发工程师", 25000);
        Employee developer3 = new Employee("吴十", "初级开发工程师", 18000);
        Employee qaEngineer = new Employee("郑一", "测试工程师", 22000);
        
        // 创建财务团队
        Employee accountant1 = new Employee("王二", "高级会计师", 28000);
        Employee accountant2 = new Employee("冯三", "会计师", 22000);
        
        // 创建HR团队
        Employee recruiter = new Employee("陈四", "招聘专员", 18000);
        Employee trainer = new Employee("褚五", "培训专员", 16000);
        
        // 构建组织架构
        // CEO下属
        ceo.add(cto);
        ceo.add(cfo);
        ceo.add(hrManager);
        
        // CTO下属
        cto.add(techManager);
        cto.add(qaEngineer);
        
        // 技术经理下属
        techManager.add(developer1);
        techManager.add(developer2);
        techManager.add(developer3);
        
        // CFO下属
        cfo.add(accountant1);
        cfo.add(accountant2);
        
        // HR经理下属
        hrManager.add(recruiter);
        hrManager.add(trainer);
        
        // 显示组织架构
        System.out.println("=== 公司组织架构 ===");
        ceo.display(0);
        
        // 统计信息
        System.out.println("\n=== 组织统计 ===");
        System.out.println("总员工数: " + ceo.getEmployeeCount() + "人");
        System.out.println("总薪资支出: ¥" + ceo.getTotalSalary());
        
        // 查找特定职位
        System.out.println("\n=== 开发工程师列表 ===");
        List<EmployeeComponent> developers = ceo.getEmployeesByPosition("中级开发工程师");
        for (EmployeeComponent dev : developers) {
            System.out.println("- " + dev.getName() + " (" + dev.getPosition() + ")");
        }
    }
}
posted @ 2025-09-11 23:59  MaC-Matthew  阅读(6)  评论(0)    收藏  举报