『設計模式』再談Macdonald的漢堡口味--策略模式

類的劃分原則
面向對象的編程,並不是類越多越好,類的劃分是爲了封裝,但分類的基礎是抽象,具有相同屬性和功能的對象的抽象集合纔是類。

策略模式

1.定義

策略模式的用意是針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發生變化。

使用策略模式可以把行爲和環境分割開來。環境類負責維持和查詢行爲類,各種算法則在具體策略類( ConcreteStrategy) 中提供。
由於算法和環境獨立開來,算法的增減、修改都不會影響環境和客戶端。當出現新的促銷折扣或現有的折扣政策出現變化時,只需要實現新的策略類,並在客戶端登記即可。策略模式相當於"可插入式(Pluggable)的算法"。
策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開,委派給不同的對象管理。
”準備一組算法,並將每一個算法封裝起來,使得它們可以互換。

2.涉及角色

環境(Context) 角色:持有一個Strategy類的引用(上下文對象),負責和具體的策略類交互。
抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現。此角色給出所有的具體策略類所需的接只。
具體策略(ConcreteStrategy) 角色:包裝了相關的算法或行爲。

3.模式講解

策略模式功能:把具體算法從具體業務處理中獨立
策略模式與if-else語句:多個if-else出現考慮使用策略模式
算法的平等性:策略算法是形同行爲的不同實現
誰來選擇具體策略算法:客戶端;由上下文來選擇具體的策略算法

4.應用場景

出現同關個算法,有很多不同的實現的情況,可以使用策略模式來把這些“不同的實現”實現成爲一個算法的類層次
出現抽象一個定義了很多行爲的類,並且是通過多個if-else語句來選擇這些行爲的情況,可以使用策略模式來代替這些條件語句

5.優點:

  • 策略模式可以避免讓客戶端涉及到不必要接觸到的複雜的和只與算法有關的數據。
  • 避免使用難以維護的多重條件選擇語句。
  • 更好的擴展。

6.缺點:

  • 上述策略模式,把分支判斷又放回到客戶端,要改變需求算法時,還是要去更改客戶端的程序。
  • 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。
  • 增加了對象的數目。
  • 只適合扁平的算法結構。

本質:分離算法,選擇實現。

深入:

  • 在策略模式中,通常是上下文使用具體的策略實現對象,反過來,策略實現對象也可以從上下文獲取所需要的數據,因此可以將上下文當參數傳遞給策略實現對象
  • 在這種情況下,上 下文封裝着具體策略對象進行算法運算所需要的數據,具體策略對象通過回調上下文的方法來獲取這些數據。

兩種方式

1.擴展上下文的方式

優點:

  • 所有策略的實現風格更統一,策略需要的數據都統一從上下文來獲取,這樣在使用方法上也很統一;
  • 在上下文中添加新的數據,別的相應算法也可以用得上,可以視爲公共的數據。

缺點:

  • 如果只有一個特定的算法來使用這些數據,那麼這些數據有些浪費;
  • 另外每次添加新的算法都去擴展上下文,容易形成複雜的上下文對象層次。
2.在策略算法的實現上添加自己需要的數據的方式

優點:

  • 比較好想,實現簡單

缺點:

  • 跟其它策略實現的風格不一致。
  • 外部使用這些策略算法的時候也不一樣了,不太好以一個統一的方式來動態切換策略算法。

實現:

UML圖:
在這裏插入圖片描述
策略接口,抽象和接口都可以

package 策略模式;

public abstract class Strategy {
	abstract public void realize_Strategy();
}

//具體的策略A

package 策略模式;

public class Concrete_Strategy_A extends Strategy {

	
	@Override
	public void realize_Strategy() {
		System.out.println("具體策略A的實現");
		
	}
}

//具體的策略B

package 策略模式;

public class Concrete_Strategy_B extends Strategy {

	
	@Override
	public void realize_Strategy() {
		System.out.println("具體策略A的實現");
		
	}
}

上下文類

package 策略模式;

public class Context {
	private Strategy str;

	public Context(Strategy str) {
		this.str = str;
	}
	public void Context_Method()
	{
		str.realize_Strategy();
	}
}

package 策略模式;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Context con;
		Strategy strA = new Concrete_Strategy_A();
		con = new Context(strA);
		con.Context_Method();
		
		Strategy strB = new Concrete_Strategy_B();
		con = new Context(strB);
		con.Context_Method();
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章