package strategy;
/**
* @author jiq
* 型別:Behavioral
* 模擬各種鴨子,會有用,呱呱叫,有的會飛,有的不會等...
* 繼承並不總是好的選擇。
* **************************************************
* 策略模式定義:
* 定義一個演算法簇,分別封裝起來,讓他們之間可以相互替換,
* 此模式讓演算法的變化獨立於使用演算法的客戶。
* **************************************************
* 遵守的OO設計原則:
* Change:不管設計的多好,軟體總會演化。
* (1)原則1:找出可能需要變化的部分,把他們與那些固定不變的部分分離開來;
* 假設鴨子可能的行為有游泳,叫,飛,以及顯示自己的描述,並且所有鴨子都一定會
* 游泳,顯示自己的描述,但是有的鴨子可能不會飛,比如橡皮鴨,或者有的不i會叫,
* 或者叫的方式不一樣等等,這些屬於變化的部分。
* (2)原則2:針對介面程式設計,而不是針對實現程式設計。
* (3)原則3:多用組合,少用繼承。
* 各種變化的行為FlyBehavior和QuackBehavior等組合到具體的鴨子類中,
* 可以在執行時動態改變鴨子的各種行為的同時,方便鴨子進行擴充。
* ********************************************************************
* 這些動態變化的部分(FlyBehavior和QuackBehavior等)組合到鴨子類中,
* 可以吧這樣的“一組行為”想象成“一簇演算法”,這就是策略模式名稱的由來。
* ********************************************************************
*/
/**
* 鴨子類固定的部分
* */
abstract class Duck{
/**
* 演算法簇(組合)/一組行為
* */
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public abstract void display();
public void swim(){
System.out.println("All duck can swim!");
}
/**
* 提供動態改變鴨子行為的介面
* */
public void setFlyBehavior(FlyBehavior f){
this.flyBehavior = f;
}
public void setQuackBehavior(QuackBehavior q){
this.quackBehavior = q;
}
/**
* 變化的部分委託給行為類
* */
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
}
/**
* 變化的部分(演算法簇)
* */
interface FlyBehavior{
public void fly();
}
interface QuackBehavior{
public void quack();
}
//////////////////////////////////////////////////
/*
* 各種鴨子
* */
class BeiJingDuck extends Duck{
public void display() {
System.out.print("I am a delicious Duck\n");
}
}
class NanJingDuck extends Duck{
public void display() {
System.out.print("I am a inteligent Duck\n");
}
}
/*
* 各種行為
* */
class FlyWithWings implements FlyBehavior{
public void fly() {
System.out.println("i fly so Slow");
}
}
class FlyRocketPowered implements FlyBehavior{
public void fly() {
System.out.println("i can fly faster than rocket");
}
}
class FemaleQuack implements QuackBehavior{
public void quack() {
System.out.println("i can quack, but not loud");
}
}
/**
* 執行時動態改變鴨子行為
* 這些鴨子都是很容易擴充的
* 可以加入各種各樣的不同的一組行為(演算法簇)而不影響現有的東東
* 各種具體的行為(飛行)可以被替換成不同的具體行為(飛行)。
* */
public class DuckSimulator {
public static void main(String[] args) {
NanJingDuck nd = new NanJingDuck();
/* 建立一支南京鴨,只能慢慢飛,像母鴨子那麼叫 */
nd.setFlyBehavior(new FlyWithWings());
nd.setQuackBehavior(new FemaleQuack());
nd.display();
nd.performFly();
nd.performQuack();
/* 突然有一天看到一支很帥很帥的鴨子,然後交配 */
//... do something you should not to see
/* 突然就變得可以像火箭那麼牛逼滴飛了 */
nd.setFlyBehavior(new FlyRocketPowered());
nd.performFly();
nd.performQuack();
}
}