序言:設計模式是程序設計中非常重要,也是非常關鍵的步驟。若能在程序設計中恰當地應用設計模式的思想,那麼代碼的質量和可維護性將會大大的提升,同時對我們的編碼水平也是一種提升。
目錄
一、概述
在策略模式(Strategy Pattern)中,一個類的行爲或其算法可以在運行時更改。這種類型的設計模式屬於行爲型模式。
在策略模式中,我們創建表示各種策略的對象和一個行爲隨着策略對象改變而改變的 context 對象。策略對象改變 context 對象的執行算法。
策略模式的定義是:定義算法族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。這算法體現了幾個設計原則,第一、把變化的代碼從不變的代碼中分離出來;第二、針對接口編程而不是具體類(定義了策略接口);第三、多用組合,少用繼承(客戶通過組合方式使用策略)。
二、結構類圖
圖片引用自:https://www.runoob.com/design-pattern/strategy-pattern.html
三、應用場景
1.如果一個系統裏有很多類,他們只是某個行爲不同時,使用策略模式可以讓一個對象在許多行爲中選擇一種行爲。
2.一個系統需要動態地在幾種算法中選擇一種。
3.有多重轉移條件語句考慮使用策略模式。
例如:在中國,知識產權局爲了鼓勵企業多多投入科技創新,每年都會對有申請知識產權保護的企業進行經濟補助,而知識產權有很多分類,比如說:專利、商標、軟件著作權等等。對於不同類型的知識產權,資助的金額標準也是不同的。因此正好可以使用策略模式,每個知識產權類型對應一個資助標準。
四、代碼示例
Fund.java 政府資助接口
/**
* 政府資助接口
*/
interface Fund {
void fund();
}
PatentStrategy.java 專利資助策略
/**
* 資助專利
*/
class PatentStrategy implements Fund{
@Override
public void fund() {
System.out.println("專利每年資助5000元");
}
}
TrademarkStrategy.java 商標資助策略
/**
* 資助商標
*/
class TrademarkStrategy implements Fund{
@Override
public void fund() {
System.out.println("商標每件資助1000元");
}
}
SoftwareCopyrightStrategy.java 軟件著作權資助策略
/**
* 資助軟件著作權
*/
class SoftwareCopyrightStrategy implements Funding{
@Override
public void fund() {
System.out.println("軟件著作權每件資助3000元");
}
}
IPR.java 知識產權對象類
class IPR<T extends Fund>{
public Fund fundStrategy;
public IPR(T fundStrategy){
this.fundStrategy = fundStrategy;
}
public void getFund(){
fundStrategy.fund();
}
}
StrategyClient,java 測試類
/**
* Created by Viking on 2019/9/22
* 策略模式案例
* 知識產權資助改進版(使用泛型)
*/
public class StrategyClientImproved {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
IPR2 patent = new IPR(new PatentStrategy());
IPR2 trademark = new IPR(new TrademarkStrategy());
IPR2 softwareCopyright = new IPR(new SoftwareCopyrightStrategy());
patent.getFund();
trademark.getFund();
softwareCopyright.getFund();
}
}
運行結果:
專利每件資助5000元
商標每件資助1000元
軟件著作權每件資助3000元
五、策略模式的優缺點
1.優點
(1).體現了“對修改關閉,對擴展開放”原則,客戶端增加行爲不用修改原有代碼,只要添加一種策略即可。
(2).避免了使用多重轉移語句(if..else if..else)。
(3).提供了可以替換繼承關係的辦法: 繼承提供了另一種支持多種算法或行爲的方法。你可以直接生成一個Context類的子類,從而給它以不同的行爲。但這會將行爲硬行編制到 Context中,而將算法的實現與Context的實現混合起來,從而使Context難以理解、難以維護和難以擴展,而且還不能動態地改變算法。最後你得到一堆相關的類 , 它們之間的唯一差別是它們所使用的算法或行爲。 將算法封裝在獨立的Strategy類中使得你可以獨立於其Context改變它,使它易於切換、易於理解、易於擴展。
2.缺點
(1).每添加一個策略就要增加一個類,當策略過多是會導致類數目龐大。
(2).客戶端需明確知道系統有哪些策略可以使用,當策略過多時客戶端的學習成本較高。
本文是在參考學習了前輩大佬的分享的基礎上,結合自己的理解和看法,重新整理了一些有自己看法的筆記。
注:文章引用部分均出自:https://www.cnblogs.com/jenkinschan/p/5645300.html