HeadFirst設(shè)計模式第一章闡述的觀點是多用組合,少用繼承.
我的理解是適當使用繼承的特性,不過度設(shè)計.
繼承可能帶來的負擔
書上用到的例子
描述鴨子這個對象 假設(shè)鴨子都有飛行這個屬性
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("玩具鴨不會飛");
}
}
這樣迭代下來會產(chǎn)生一個問題 需要關(guān)注的屬性太多
每一個派生的鴨子 都需要重寫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");
}
}
再次描述鴨子的派生鴨子 都只需要動態(tài)指定鴨子的組成行為
public class GreenDuck extends Duck {
public GreenDuck(DuckBehavior behavior)
{
mBehavior = behavior;
}
}
組合替代繼承之后,鴨子的邏輯更加清晰.
維護者只需要分別維護鴨子和鴨子行為的邏輯
組合和繼承的選擇
組合是has-a關(guān)系,繼承是is-a關(guān)系
未完待續(xù)......