设计模式

组合替代继承

2019-02-28  本文已影响0人  cx7

HeadFirst设计模式第一章阐述的观点是多用组合,少用继承.
我的理解是适当使用继承的特性,不过度设计.

继承可能带来的负担

书上用到的例子
描述鸭子这个对象 假设鸭子都有飞行这个属性

public class Duck {
    public void fly() {
        System.out.println("鸭子的飞行属性");
    }
}

鸭子的实际对象野鸭会飞

public class YieldDuck extends Duck {
    public void fly() {
        System.out.println("野鸭会飞");
    }
}

鸭子的实际对象玩具鸭不会飞

public class MachineDuck extends Duck {
    public void fly() {
        System.out.println("玩具鸭不会飞");
    }
}

这样迭代下来会产生一个问题 需要关注的属性太多
每一个派生的鸭子 都需要重写fly方法来确定飞行这个属性
如果鸭子有飞行, 游泳,跑步...属性越多 继承的负担就越重

利用组合来避开可能的负担

把鸭子的飞行抽象成一种行为

public class Duck {

    protected DuckBehavior mBehavior;

    public interface DuckBehavior {
        void fly();
    }

    protected void fly() {
        mBehavior.fly();
    }

}

这样会不会飞可以分别描述
会飞的行为

public class DuckCanFlyBehavior implements Duck.DuckBehavior{

    @Override
    public void fly() {
        System.out.println("DuckCanFlyBehavior fly");
    }

}

不会飞的行为

public class DuckCantFlyBehavior implements Duck.DuckBehavior{

    @Override
    public void fly() {
        System.out.println("DuckCantFlyBehavior fly");
    }

}

再次描述鸭子的派生鸭子 都只需要动态指定鸭子的组成行为

public class GreenDuck extends Duck {

    public GreenDuck(DuckBehavior behavior)
    {
        mBehavior = behavior;
    }

}

组合替代继承之后,鸭子的逻辑更加清晰.
维护者只需要分别维护鸭子和鸭子行为的逻辑

组合和继承的选择

组合是has-a关系,继承是is-a关系
未完待续......

上一篇下一篇

猜你喜欢

热点阅读