政策者模式,是要解決某類正常思想設計容易帶來問題的問題。
請看如下案例:
1、模拟鴨子項目 2、項目的新需求 3、用OO原則解決新需求的不足 4、用政策模式來新需求解決 5、重新設計模拟鴨子項目 6、總結政策模式定義
政策模式原理
1、從項目"模拟鴨子遊戲"開始 2、從OO的角度設計這個項目,鴨子超類,擴充超類: public abstract class Duck {
public void Quack() {
System.out.println("~~gaga~~");
}
public abstract void display();
public void swim() {
System.out.println("~~im swim~~");
}
}
模拟鴨子項目
1、GreenHeadDuck繼承Duck : public class GreenHeadDuck extends Duck {
@Override
public void display() {
System.out.println("**GreenHead**");
}
}
2、同理可有RedHeadDuck等
模拟鴨子項目
1、應對新的需求,看看這個設計的可擴充性 1)添加會飛的鴨子 2、OO思維裡的繼承方式解決方案是: public abstract class Duck {
...;
public void Fly() {
System.out.println("~~im fly~~");
}
}; 問題來了,這個Fly讓所有子類都會飛了,這是不科學的。 繼承的問題:對類的局部改動,尤其超類的局部改動,會影響其他部分。影響會有溢出效應
項目的新需求
1、繼續嘗試用OO原理來解決,覆寫:
public class GreenHeadDuck extends Duck { ...; public void Fly()
{ System.out.println("~~no fly~~"); } }
2、又有新需求,石頭鴨子,填坑:
public class StoneDuck extends Duck { ....
};
超類挖的一個坑,每個子類都要來填,增加工作量,複雜度O(N^2)。不是好的設計方式
用OO原則解決新需求的不足
需要新的設計方式,應對項目的擴充性,降低複雜度:
1)分析項目變化與不變部分,提取變化部分,抽象成接口+實作;
2)鴨子哪些功能是會根據新需求變化的?叫聲、飛行...
用政策模式來新需求解決
1、接口:
1)
public interface FlyBehavior {
void fly();
}
2)
public interface QuackBehavior {
void quack();
};
3)好處:新增行為簡單,行為類更好的複用,組合更友善。既有繼承帶來的複用好處,沒 有挖坑
用政策模式來新需求解決
1、重新設計的鴨子項目:
public abstract class Duck {
FlyBehavior mFlyBehavior;
QuackBehavior mQuackBehavior;
public Duck() {
}
public void Fly() {
mFlyBehavior.fly();
}
public void Quack() {
mQuackBehavior.quack();
}
public abstract void display();
}
重新設計模拟鴨子項目
1、綠頭鴨、石頭鴨: public class GreenHeadDuck extends Duck { public GreenHeadDuck() { mFlyBehavior = new GoodFlyBehavior(); mQuackBehavior = new GaGaQuackBehavior(); } @Override public void display() {...} } 2、政策模式:分别封裝行為接口,實作算法族,超類裡放行為接口對象,在子類裡具體設 定行為對象。原則就是:分離變化部分,封裝接口,基于接口程式設計各種功能。此模式讓行為 算法的變化獨立于算法的使用者。
繼承的問題:對類的局部改動,尤其是超類的局部改動,會影響其他部分,影響會有溢出效應:
了解一:政策(Strategy)模式是行為模式之一,它對一系列的算法加以封裝,為所有算法定義一個抽象的算法接口,并通過繼承該抽象算法接口對所有的算法加以封裝和實作,具體的算法選擇交由用戶端決定(政策)。政策模式主要用來平滑地處理算法的切換。
了解二:政策模式分别封裝行為接口,實作算法組,超類裡面放行為接口對象,子類裡面具體設定為對象。原則就是:分離變化部分,封裝接口,基于接口程式設計各種功能,此模式讓行為算法的變化,獨立于算法的使用者。