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关系
未完待续......
网友评论