策略模式
是指對一系列的算法定義,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
抽象策略角色: 策略類,通常由一個接口或者抽象類實現。
具體策略角色:包裝了相關的算法和行爲。
環境角色:持有一個策略類的引用,最終給客戶端調用。
應用場景:
1、 多個類只區別在表現行爲不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行爲。
2、 需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實現。
3、 對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立代碼
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy=strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void operate(){
this.strategy.operate();
}
}
public class BackDoor implements Strategy {
@Override
public void operate() {
System.out.print("找喬國老幫忙,讓吳國太給孫權施加壓力,使孫權不能殺劉備");
}
}
public interface Strategy {
void operate();
}
public class GivenGreenLight implements Strategy {
@Override
public void operate() {
System.out.println("求吳國太開個綠燈,放行");
}
}
public class BlackEnemy implements Strategy {
@Override
public void operate() {
System.out.println("孫夫人斷後,擋住追兵");
}
}
測試代碼
public class StrategyMethodActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_strategy_method);
Context context=new Context(new BackDoor());
context.operate(); System.out.println("\n"); context.setStrategy(new GivenGreenLight()); context.operate(); System.out.println("\n"); context.setStrategy(new BlackEnemy()); context.operate(); System.out.println("\n"); }}優點:
1、 策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族。恰當使用繼承可以把公共的代碼轉移到父類裏面,從而避免重複的代碼。
2、 策略模式提供了可以替換繼承關係的辦法。繼承可以處理多種算法或行爲。如果不是用策略模式,那麼使用算法或行爲的環境類就可能會有一些子類,每一個子類提供一個不同的算法或行爲。但是,這樣一來算法或行爲的使用者就和算法或行爲本身混在一起。決定使用哪一種算法或採取哪一種行爲的邏輯就和算法或行爲的邏輯混合在一起,從而不可能再獨立演化。繼承使得動態改變算法或行爲變得不可能。
3、 使用策略模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把採取哪一種算法或採取哪一種行爲的邏輯與算法或行爲的邏輯混合在一起,統統列在一個多重轉移語句裏面,比使用繼承的辦法還要原始和落後。
缺點:
1、客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用於客戶端知道所有的算法或行爲的情況。
2、 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。有時候可以通過把依賴於環境的狀態保存到客戶端裏面,而將策略類設計成可共享的,這樣策略類實例可以被不同客戶端使用。換言之,可以使用享元模式來減少對象的數量。
github地址:https://github.com/zyj18410105150/DesignMode