合成复用原则(Composite Reuse Principle)

1. 概念

  • 尽量使用对象聚合/组合,而不是继承关系达到软件复用的目的

2. 聚合vs组合vs继承

  • 聚合(aggregation):has-A
  • 组合(composition):contains-A
  • 继承(inheritance):is-A

3. 继承复用 vs 合成复用

  • 继承复用
    • 优点:简单,容易实现
    • 缺点:破坏了封装性,耦合度高,限制灵活性
  • 合成复用
    • 优点:维持封装性,降低耦合度,灵活性高
    • 缺点:有较多的对象需要管理

3. 代码示例

需求
  • 创建不同能源不同颜色的车
示例1
  • 分析
    • 每加一种能源的车或者每增加一种新的颜色,对应的类会成倍增加(拓展困难)
package com.bz.pattern.composite;

/**
 * 用于创建不同能源不同颜色的车
 */
public class CarMaker {

    public static void main(String[] args) {
        RedGasoLineCar c1 = new RedGasoLineCar();
        c1.move();
    }
}

class GasoLineCar {
    public void move() {
        System.out.println("GasoLineCar move");
    }
}

class ElectricCar {
    public void move() {
        System.out.println("ElectricCar move");
    }
}

class RedGasoLineCar extends GasoLineCar {
    @Override
    public void move() {
        System.out.println("Red GasoLineCar move");
    }
}

class BlueGasoLineCar extends GasoLineCar {
    @Override
    public void move() {
        System.out.println("Blue GasoLineCar move");
    }
}

示例2
  • 合成复用改进(易扩展)
package com.bz.pattern.composite;

public class CarMakerImprove {
    public static void main(String[] args) {
        Car car1 = new Car(new GasoLine(), new Red());
        car1.move();
        Car car2 = new Car(new GasoLine(), new Blue());
        car2.move();
    }
}

class Car {
    private Energy energy;
    private Color color;

    public Car(Energy energy, Color color) {
        this.energy = energy;
        this.color = color;
    }

    public void move() {
        System.out.println(color.getName() + energy.getName()  + "move");
    }
}

interface Energy {
    String getName();
}

class GasoLine implements Energy {
    @Override
    public String getName() {
        return " GasoLine ";
    }
}

class Electric implements Energy {
    @Override
    public String getName() {
        return " Electric ";
    }
}

interface Color {
    String getName();
}

class Red implements Color {
    @Override
    public String getName() {
        return "Red";
    }
}

class Blue implements Color {
    @Override
    public String getName() {
        return "Blue";
    }
}

4. 注意事项

  • 聚合/组合 > 继承
上一篇:MySQL的InnoDB引擎的事务原理以及MVCC


下一篇:springboot基于vue的MOBA类游戏攻略分享平台