策略模式一直程序開發中,最經常使用的模式之一;它的功能就是定義了一系列的算法,這些算法定義着公共的接口,因此它們之間能夠相互替換。這使得咱們在開發過程當中,如有新的策略須要擴展時,程序變的很容易開發。下面是策略模式的結構示意圖:java
從結構示意圖中,咱們能清楚的感覺到,策略模式的巧妙之處就是將變化的東西(這裏咱們稱之爲算法)經過定義一個相同的公共的接口封裝且隔離;以不一樣的策略實現相同的接口,使程序可以完成各類任務的同時,讓上層的編程針對接口,實現不變,也不關心其調用的是哪一種策略。算法
然而在實際開發中,咱們的需求每每不會像結構示意圖那樣,如此簡單、如此simple。實際較爲常見的狀況就是:上層的調用須要與接口之間有必定的交互。交互的多是一些屬性,或是一些方法。這樣的交互每每會讓接口變的難以調用;因而上下文的引入就是勢在必行。將相關的屬性或一些公共的方法封裝到上下文中,讓上下文去和接口進行復雜的交互。而上層的調用只須要跟上下文打交道就能夠。下面有包含上下文的策略模式結構示意圖:編程
仔細看看兩個結構示意圖的變化,其實不外乎將變的東西和不變的東西進行封裝與隔離,這樣不變的東西可以儘量的減少其變化,而變的東西更容易修改或擴充;其實這也正是軟件設計的基本原則。ide
透過示意圖,咱們上下文對象,將本身傳遞給接口,方便接口調取它的屬性與方法,以完成交互。如此將前面提到的交互的行爲提取出來,封裝在本身內部,對上層提供統一調用方法。也正是將變化與不變封裝且隔離。this
正如前面提到的,上下文中封裝了上層調用類與接口間的交互;但這些交互有個前提,那就是它們能被抽象出來。另外一些交互在咱們的業務需求中沒法被抽象出來。換句話說,這些交互,就是要延遲到上層調用內中來設計與實現的。在這種狀況下:上層調用類與接口的某個策略的實現每每是緊耦合的、而且它們是一對一。spa
要完成它們之間的這種交互,設計它們間通信的方法,會讓代碼變雜亂,同時也增長了調用接口的難度。.net
這時內部類的優點能夠在此發揮:咱們將接口的實現類放到上層調用類中,變成上層調用類的一個內部類;因爲內部類能夠任意調用其外部類的屬性和方法的特性。它們能直接的無阻礙的通信,徹底不一樣設計多餘的接口方法來完成交互;如此一來也正好符合它們一對一的關係。下面是我簡單寫的一個小Demo:設計
策略接口:code
/** * 策略算法接口 * @author Breath_L * */ public interface Strategy { public void doStrategy(Context cont); }
上下文類:orm
/** * 上下文類 * @author Breath_L * */ public class Context { private String baseTxt; private Strategy strategy; public Context(String baseTxt, Strategy strategy){ this.baseTxt = baseTxt; this.strategy = strategy; } /** * 暴露給上層對象調用的方法 */ public void doStrategyNow(){ //公共邏輯... System.out.println(baseTxt); strategy.doStrategy(this); //公共邏輯... } }
上層調用類:
public class TopGetter { public Strategy in_strategy; public Context context; public TopGetter(){ in_strategy = new Strategy(){ @Override public void doStrategy(Context cont) { System.out.println(beDependent()); } }; context = new Context("Hello World !", in_strategy); } private String beDependent(){ return "We will rock you !"; } public void startHere(){ context.doStrategyNow(); } public static void main(String[] args){ TopGetter topGetter = new TopGetter(); topGetter.startHere(); } }
仔細思考上下文和內部類,它們算是策略模式在封裝和隔離變與不變的東西時,的一個深刻設計。萬變不離其中的仍是軟件設計的基本原則。仍是那句話:沒有最完美的設計,只有最符合業務的實現。也許此刻的思考只是符合我最近的業務,不怕見笑,作一下記錄與分享。
原創博客,轉載請註明:http://my.oschina.net/BreathL/blog/52655