组合模式

组合模式是一种结构型设计模式,用于表示对象的树形结构,允许我们像处理简单对象一样处理复杂对象。在组合模式中,树枝和叶子节点实现了相同的接口,使得整体和部分的操作一致。这种模式常用于文件系统、组织结构等场景,但要注意它可能违反依赖倒置原则。在Java中,可以通过创建一个模型类来组合相似对象,通过添加和删除方法实现树形结构的构建和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、组合模式的概念

组合模式,英文Composite Pattern,也称为部分整体模式,属于结构型模式。该模式将一组相似对象当成一个整体对象,使用树形结构来组合对象,来表示部分以及整体层次。该模式创建一个包含自己对象组的类,然后在该类中提供修改相同对象组的方法。

2、组合模式的特点

  • 使用树形结构来组合对象。
  • 将相似对象组合成一个整体,表示整体和部分层次。

3、关于组合模式

  • 使用目的:将对象组合成树形结构来表示整体和部分层次。
  • 解决问题:在树形结构中,模糊了简单元素和复杂元素,可以让我们像处理简单元素一样的处理复杂元素,在一定程度上使得客户程序和复杂元素的内部结构解耦。
  • 使用时机
    • 想表示对象的整体-部分层次结构时,可以使用树形结构。
    • 忽略组合对象和单个对象的不同,统一地使用组合结构中的所有对象。
  • 保证组合:树枝和叶子实现统一接口,然后在树枝内部来组合该接口。
  • 组合关键:树枝内部组合接口,包含List类型的成员属性,里面封装对象。

4、组合模式的优缺点

优点:

  • 高层模块调用简单。
  • 节点可以自由增加。

缺点:

  • 在组合时,树枝和叶子都是实现类,而不是接口,违反了依赖倒置原则。

5、组合模式的使用场景

  • 部分整体层次,比如树形结构,文件夹以及文件的组合形式。

6、组合模式的实现

(1)创建模型类

注意的是,树枝和叶子都是相同类型的对象,使用同一个模型类来定义,如下:

/*
 * 组合模型类
 * 用来组合相似的一组对象
 */
public class Employee {

    // 职务
    private String position;

    // 员工姓名
    private String empName;

    // 员工薪水
    private double salary;

    // 管辖下属,注意这里是一个List类型的成员属性,用来组合该类对象
    private List<Employee> subornaties = new ArrayList<>();
    
    // 构造方法
    public Employee(String position,String empName,double salary) {
        this.position = position;
        this.empName = empName;
        this.salary = salary;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public List<Employee> getSubornaties() {
        return subornaties;
    }

    public void setSubornaties(List<Employee> subornaties) {
        this.subornaties = subornaties;
    }

    @Override
    public String toString() {
        return "员工信息=====》[所属职务:" + this.getPosition() 
               + ",姓名:" + this.getEmpName() 
               + ",薪资:" + this.getSalary() + "]";
    }

    // 自定义方法,添加员工到List集合中
    public void addEmployee(Employee emp) {
        subornaties.add(emp);
    }

    // 从List集合中移除员工
    public void delEmployee(Employee emp) {
        subornaties.remove(emp);
    }

}

(2)测试

public class Test {

    public static void main(String[] args){
        Employee emp0 = new Employee("公司Boss", "李狗蛋", 50000.0);
        Employee emp2 = new Employee("技术部负责人","王尼玛", 20000.0);
        Employee emp3 = new Employee("技术部码农","张三", 10000.0);
        Employee emp4 = new Employee("技术部码农","李四", 7000.0);
        Employee emp5 = new Employee("技术部码农","yanchengzhi", 8000.0);
        Employee emp6 = new Employee("销售部负责人", "卖货老王", 30000.0);
        Employee emp7 = new Employee("销售部员工", "李永", 15000.0);
        Employee emp8 = new Employee("销售部员工", "刘刚", 12000.0);
        Employee emp9 = new Employee("人事部负责人", "孙雪", 10000.0);
        Employee emp10 = new Employee("人事部员工", "周星星", 8500.0);
        Employee emp11 = new Employee("人事部员工", "何晓琳", 7800.0);
        // 组合成树形结构
        // boss直辖各部门负责人
        emp0.addEmployee(emp2);
        emp0.addEmployee(emp6);
        emp0.addEmployee(emp9);
        // 技术部负责人直辖技术部员工
        emp2.addEmployee(emp3);
        emp2.addEmployee(emp4);
        emp2.addEmployee(emp5);
        // 销售部负责人直辖销售部员工
        emp6.addEmployee(emp7);
        emp6.addEmployee(emp8);
        // 人事部负责人直辖人事部员工
        emp9.addEmployee(emp10);
        emp9.addEmployee(emp11);
        System.out.println("boss统辖:");
        System.out.println("-------------------------------------------------------");
        List<Employee> leaders = emp0.getSubornaties();
        for(Employee leader:leaders) {
            System.out.println(leader.toString());
            System.out.println(leader.getPosition() + "统辖:");
            List<Employee> employees = leader.getSubornaties();
            for(Employee e:employees) {
                System.out.println(e.toString());
            }
            System.out.println("-------------------------------------------------------");
        }
    } 

}

在这里插入图片描述
7、小结

组合模式最经典的代表就是树形结构,树枝和叶子节点的组合形式,以及我们电脑上的文件系统,文件夹和具体文件的组合形式。当需要用到整体-部分层次结构时,可以考虑使用组合模式来实现,但是前提是父节点和子节点属于同一类型对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值