0107_合成复用原则

定义:优先使用对象组合/聚合,而不是继承来达到复用的目的

场景

还以人类为例,人类动作有吃饭、行走、跑、跳。前面都是几篇文章都是通过继承实现,这篇文章通过组合来实现。
SportBehavior
LifeBehavior接口

  • 职责:基础生命行为接口,定义了生物体的基本行为规范
public interface LifeBehavior {
    /**
     * 吃饭行为
     */
    void eat();
    
    /**
     * 走路行为
     */
    void walk();
}

BasicLifeBehavior类

  • 职责:实现了LifeBehavior接口,提供基本的生命行为功能
public class BasicLifeBehavior implements LifeBehavior {
    /**
     * 生命体名称
     */
    private String name;
    
    /**
     * 构造方法,初始化生命体名称
     * @param name 生命体名称
     */
    public BasicLifeBehavior(String name) {
        this.name = name;
    }
    
    /**
     * 实现吃的行为
     * 输出"[name]在吃饭"的信息
     */
    @Override
    public void eat() {
        System.out.println(name + "在吃饭");
    }
    
    /**
     * 实现走的行为
     * 输出"[name]在走路"的信息
     */
    @Override
    public void walk() {
        System.out.println(name + "在走路");
    }
}

SportBehavior接口

  • 职责:运动行为接口,定义了基本的运动行为规范
public interface SportBehavior {
    /**
     * 跑步行为
     * 实现该方法以提供跑步功能
     */
    void run();
    
    /**
     * 跳跃行为
     * 实现该方法以提供跳跃功能
     */
    void jump();
}

BasicSportBehavior类

  • 职责:实现了SportBehavior接口,提供基本的跑步和跳跃功能
public class BasicSportBehavior implements SportBehavior {
    /**
     * 运动者名称
     */
    private String name;
    
    /**
     * 构造方法,初始化运动者名称
     * @param name 运动者名称
     */
    public BasicSportBehavior(String name) {
        this.name = name;
    }
    
    /**
     * 实现跑步行为
     * 输出指定名称的跑步信息
     */
    @Override
    public void run() {
        System.out.println(name + "在跑步");
    }
    
    /**
     * 实现跳跃行为
     * 输出指定名称的跳跃信息
     */
    @Override
    public void jump() {
        System.out.println(name + "在跳跃");
    }

BaseHuman类

  • 职责:人类实现类,通过组合不同的行为实现来构建完整功能
public class BaseHuman implements LifeBehavior, SportBehavior {
    // 使用组合而不是直接实现行为
    private LifeBehavior lifeBehavior;
    private SportBehavior sportBehavior;
    private String name;
    
    /**
     * 构造函数,初始化人类对象
     * @param name 人类姓名
     */
    public BaseHuman(String name) {
        this.name = name;
        // 初始化基础生命行为
        lifeBehavior = new BasicLifeBehavior(name);
        // 初始化基础运动行为
        sportBehavior = new BasicSportBehavior(name);
    }
    
    /**
     * 实现吃饭行为,委托给lifeBehavior处理
     */
    @Override
    public void eat() {
        lifeBehavior.eat();
    }
    
    /**
     * 实现走路行为,委托给lifeBehavior处理
     */
    @Override
    public void walk() {
        lifeBehavior.walk();
    }
    
    /**
     * 实现跑步行为,委托给sportBehavior处理
     */
    @Override
    public void run() {
        sportBehavior.run();
    }
    
    /**
     * 实现跳跃行为,委托给sportBehavior处理
     */
    @Override
    public void jump() {
        sportBehavior.jump();
    }
}

总结

通过对象组合而非继承来实现代码复用,将不同的行为职责分离到独立的组件中,然后通过组合的方式构建完整的对象功能。
相比于继承方式的优点:

  1. 灵活性更强

    • 可以动态替换行为实现(如更换不同的运动方式)
    • 不需要通过复杂的继承层次来扩展功能
  2. 避免继承爆炸

    • 不需要为每种行为组合创建子类(如会跑步的人、会跳跃的人等)
  3. 更好的代码复用

    • 行为组件可以在不同的类中重用
    • 避免代码重复和冗余
  4. 符合开闭原则

    • 扩展新行为时不需要修改现有代码
    • 只需实现新的行为组件即可

这种组合方式特别适合:

  • 需要多种独立行为组合的对象
  • 行为可能需要动态变化的场景
  • 希望避免深层次继承结构的系统
  • 需要高度可配置和可扩展的设计
posted @ 2025-08-22 00:04  庞去广  阅读(10)  评论(0)    收藏  举报