【大話設計模式】——策略模式
一、開篇
上篇文章【大話設計模式】——簡單工廠模式告訴了我們一個網咖收費工廠物件如何建立收費形式(白天收費、夜間收費)的例項。簡單工廠程式碼中有很多 case分支語句 ,如果我們還想填加收費的形式(比如會員收費啊,通宵收費啊),就需要改動工廠程式碼,每次維護和擴充套件都要花費很多時間,另外改動很容易造成紕漏(比如之前的白天收費形式,很可能因為改動從多收錢或者少收錢),所以簡單工廠模式很不安全。所以我們要把經常變化的程式碼抽象出來,做到業務邏輯和介面邏輯分開,只有這樣才能更加容易做到維護和擴充套件。
發現問題,解決問題,人類就這樣一點一滴的進步著。
發現了簡單工廠的不好,策略模式就誕生啦,人類真的是很睿智!(呱唧呱唧)
下面大家熟悉一下策略模式的定義:
策略模式(Strategy):它定義了演算法家族,分別封裝起來,讓她們之間可以互相替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。
二、UML圖
Context(環境類):需要使用ConcreteStrategy的具體演算法,維護一個對Strategy物件的引用,負責跟Strategy之間的互動和資料傳遞。
Strategy(抽象策略類):定義所有支援的演算法的公共介面。Context使用這個介面來呼叫ConcreteStrategy演算法。
ConcreteStrategy(具體策略類):封裝了具體的演算法和行為,繼承與Strategy.
圖中含有兩種關係,聚合和繼承。
三、例項解析
比如我們填飽肚子的方式,有幾個策略可以考慮:吃水果、吃蔬菜、吃饅頭。首先定義一個抽象類吃,然後讓吃的形式:吃水果,吃蔬菜,吃饅頭繼承這個抽象吃類,再宣告一個Context類,用來配置吃的方法,維護一個對Strategy物件的引用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)//客戶端程式碼
{
Context context;
context = new Context(new EatingFruit());//例項化不同的策略,呼叫的時候獲得的結果就不同。
context.ContextInterface();
context = new Context(new EatingVegetables());
context.ContextInterface();
context = new Context(new EatingSteamBread());
context.ContextInterface();
}
}
abstract class EatStrategy//抽象吃法類
{
public abstract void Eat();
}
class EatingFruit:EatStrategy //具體吃法吃蘋果
{
public override void Eat()
{
Console .WriteLine ("餓了吃蘋果");
}
}
class EatingVegetables : EatStrategy//具體吃法吃蔬菜
{
public override void Eat()
{
Console .WriteLine ("吃蔬菜也不餓");
}
}
class EatingSteamBread : EatStrategy//具體吃法吃饅頭
{
public override void Eat()
{
Console .WriteLine ("吃饅頭也不錯");
}
}
class Context//寫策略環境類
{
EatStrategy eatstrategy;
public Context(EatStrategy eatstrategy)//初始化時,傳入具體的策略物件
{
this.eatstrategy = eatstrategy;
}
//上下文介面
public void ContextInterface()//根據具體的策略物件,呼叫其演算法的方法
{
eatstrategy.Eat();
}
}
}
四、總結
策略模式的優點:
1)所有的演算法完成相同的工作,只是實現不同,它以相同的方式呼叫所有的演算法,減少了各種演算法類與使用演算法類之間的耦合。
個人理解:不管是吃水果還是吃蔬菜,異或是吃饅頭,都是為了填飽肚子,雖然形式不同,如果有的人挑食吃飯一定要吃菜加饅頭才肯吃,那如果沒有賣饅頭的,你就要減肥啦~
2)策略模式Strategy類層次為Context定義了一系列的可供重用的演算法和行為。繼承有助於析取出這些演算法中的公共功能。
個人理解:把東西分類放置,使用的時候就更加容易找到。
3)簡化了單元測試,因為每個演算法都有自己的類,可以通過自己的介面單獨測試。
個人理解:有單獨的類,就更容易滿足單一職責原則,這樣測試一個功能,資料如果不對,直接就能劃分出範圍。比如值日分為掃地和擦桌子,安排小明拖地,小紅擦桌子。如果值完日了,地面還髒,那肯定就是小明乾的不好唄(當然排除搞破壞的可能)。但是如果你讓兩個人幹活,又沒有分配任務,那好了,挨罰就兩個人一起做個伴吧!
4)演算法封裝在單獨的類中,可以消除條件語句,為客戶端減輕了壓力。
個人理解:領導者如果負責一個很龐大的工程的話,那些瑣事會讓他侷限於細節,而失去了把控能力。
缺點:
1)客戶端必須知道所有的策略類,並自行決定使用哪個策略類。
2)Strategy和Context之間存在通訊開銷
3)如果具體策略過多,會產生很多的策略類,增加了維護的難度。
程式碼即人生啊~
相關文章
- 大話--策略模式模式
- 大話設計模式設計模式
- 【設計模式】設計模式(一)-- 大話設計模式讀書筆記設計模式筆記
- 設計模式(策略模式)設計模式
- 設計模式-策略模式設計模式
- 設計模式——策略模式設計模式
- 軟體設計模式白話文系列(十四)策略模式設計模式
- Unity【話大】設計模式之狀態模式Unity設計模式
- 小白設計模式:策略模式設計模式
- 設計模式之策略模式設計模式
- 設計模式🔫---策略模式設計模式
- js設計模式--策略模式JS設計模式
- 設計模式之【策略模式】設計模式
- 設計模式 #5 (策略模式、代理模式)設計模式
- 【設計模式】漢堡中的設計模式——策略模式設計模式
- Javascript設計模式(四)策略模式JavaScript設計模式
- PHP設計模式(3)—— 策略模式PHP設計模式
- JS設計模式六:策略模式JS設計模式
- 《Head First 設計模式》:策略模式設計模式
- PHP 設計模式之策略模式PHP設計模式
- python設計模式之策略模式Python設計模式
- Java設計模式-策略模式分析Java設計模式
- JavaScript 設計模式之策略模式JavaScript設計模式
- 設計模式專題-策略模式設計模式
- 設計模式(一) 支付策略模式設計模式
- Javascript設計模式之策略模式JavaScript設計模式
- 極簡設計模式-策略模式設計模式
- 略懂設計模式之策略模式設計模式
- GoLang設計模式15 - 策略模式Golang設計模式
- JAVA設計模式之策略模式Java設計模式
- 23種設計模式(二)---策略設計模式設計模式
- 大話 PHP 設計模式--建立型PHP設計模式
- 設計模式第二講--策略模式設計模式
- 設計模式漫談之策略模式設計模式
- javascript設計模式 之 2 策略模式JavaScript設計模式
- Head First 設計模式(1)-----策略模式設計模式
- c/c++設計模式---策略模式C++設計模式
- Java設計模式之(十四)——策略模式Java設計模式
- 細品 javascript 設計模式(策略模式)JavaScript設計模式