初始設計:Duck 抽象類定義 quack()、fly()、swim(),子類繼承覆寫。問題:
RubberDuck(不會飛、吱吱叫)→ 需覆寫 fly() 為空、quack() 改行為DecoyDuck(不會飛、不會叫)→ 又要覆寫兩方法定義 Flyable、Quackable 介面,會飛/會叫的子類實現。缺點:代碼無法復用,每個子類仍需各自實現介面方法,維護成本不降反增。
找出應用中可能變化的部分,把它們獨立出來,不要和那些不變的混在一起。
—— 封裝變化
針對介面編程,而不是針對實現編程。
—— 多態與解耦
多用組合,少用繼承。
—— 靈活性與復用
public interface FlyBehavior { void fly(); }
public interface QuackBehavior { void quack(); }
// 飛行
public class FlyWithWings implements FlyBehavior { public void fly() { System.out.println("用翅膀飛"); } }
public class FlyNoWay implements FlyBehavior { public void fly() { System.out.println("不會飛"); } }
public class FlyRocketPowered implements FlyBehavior { public void fly() { System.out.println("火箭動力飛行!"); } }
// 叫聲
public class Quack implements QuackBehavior { public void quack() { System.out.println("呱呱叫"); } }
public class Squeak implements QuackBehavior { public void quack() { System.out.println("吱吱叫"); } }
public class MuteQuack implements QuackBehavior { public void quack() { System.out.println("沉默"); } }
public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
public Duck() {
this.flyBehavior = new FlyWithWings(); // 預設行為
this.quackBehavior = new Quack();
}
public void performFly() { flyBehavior.fly(); }
public void performQuack() { quackBehavior.quack(); }
public void swim() { System.out.println("游泳"); }
public abstract void display();
// 運行時動態改變行為
public void setFlyBehavior(FlyBehavior fb) { this.flyBehavior = fb; }
public void setQuackBehavior(QuackBehavior qb) { this.quackBehavior = qb; }
}
public class MallardDuck extends Duck {
public MallardDuck() {
// 可選:在構造器指定特定行為
}
public void display() { System.out.println("綠頭鴨"); }
}
public class RubberDuck extends Duck {
public RubberDuck() {
setFlyBehavior(new FlyNoWay());
setQuackBehavior(new Squeak());
}
public void display() { System.out.println("黃色橡皮鴨"); }
}
Duck modelDuck = new ModelDuck();
modelDuck.performFly(); // 不會飛
modelDuck.setFlyBehavior(new FlyRocketPowered());
modelDuck.performFly(); // 火箭動力飛行!

| 維度 | 繼承方案 | 介面方案 | 策略模式(組合) |
|---|---|---|---|
| 代碼復用 | 低(需覆寫) | 無(各自實現) | 高(行為類復用) |
| 靈活性 | 編譯時固定 | 編譯時固定 | 運行時動態切換 |
| 類數量 | 指數增長 | 線性增長 | 行為類 + 鴨子類,正交 |
| 符合原則 | 違反封裝變化 | 部分符合 | 完美符合三大原則 |
策略模式定義了算法族,封裝每個算法,使它們可互換,讓算法變化獨立於使用算法的客戶。