天天看點

php中政策模式,PHP 政策模式

政策模式(Strategy):它定義了算法家族,分别封裝起來,讓他們之間可以互相替換,此模式讓算法的變化不會影響到使用算法的客戶。

政策模式是一種定義一系列算法的方法,從概念上來看,所有這些算法完成的都是相同的工作,隻是實作不同,它可以以相同的方式調用所有的算法,減少了各種算法類與使用算法類之間的耦合。事實上你可以将一個繼承自抽象政策類的稱為具體政策,就是政策模式中的政策1,政策2......

政策模式的優點:

政策模式的Strategy類層次為Context定義了一系列的可供重用的算法或行為。繼承有助于析取出這些算法的公共功能。政策模式的另一個優點是簡化了單元測試,因為每個算法都有自己的類,可以通過自己的接口單獨測試。

說了這麼多,政策模式究竟解決的是什麼問題呢?

政策模式就是用來封裝算法的,但在實踐中,我們發現可以用它來封裝幾乎任何類型的規則,隻要在分析過程中聽到需要在不同時間應用不同的業務規則,就可以考慮使用政策模式處理這種變化的可能性。

在基本政策模式中,選擇所用具體實作的職責由用戶端對象承擔,并轉給政策模式的Context對象。

政策模式的結構圖:

php中政策模式,PHP 政策模式

政策模式的具體實作代碼示例:

namespace 政策模式

{

public class Program

{

static void Main(string[] args)

{

Console.WriteLine("我釣了一條魚,應該怎麼煮呢?");

Context context;

context = new Context(new ConcreteStrategyA());  //用戶端依賴具體實作類了

context.RunMethod();

context = new Context(new ConcreteStrategyB());

context.RunMethod();

Console.ReadKey();

}

}

//抽象算法類

public abstract class Strategy

{

//算法方法

public abstract void AlgorithmInterface();

}

//具體政策1

public class ConcreteStrategyA : Strategy

{

public override void AlgorithmInterface()

{

Console.WriteLine("加水、上蒸籠、開火、清蒸!");

}

}

//具體政策2

public class ConcreteStrategyB : Strategy

{

public override void AlgorithmInterface()

{

Console.WriteLine("熱鍋、放油、紅燒!");

}

}

//上下文

public class Context

{

Strategy strategy;

//構造方法接收具體對象

public Context(Strategy strategy)

{

this.strategy = strategy;

}

//調用方法

public void RunMethod()

{

strategy.AlgorithmInterface();

}

}

}

複制代碼

以上代碼感覺到了什麼?政策模式不管建立,它做的事非常少,少到什麼程度?

你傳個對象給我,我幫你調用這個對象的方法(這個工作主要通過Context來維護),我不管你這對象怎麼建立,但你得給我個對象。政策模式不管對象的建立,那麼它實質上是什麼。用類圖說明。

php中政策模式,PHP 政策模式

從上面的類圖看到一個問題。因為,我調用你時,我要給你傳個對象,上面的例子直接new()。是以,用戶端依賴于具體實作類了。

是以,政策模式通常與一些建立對象的模式混合使用,比如負責維護調用具體政策的Context類搭配個簡單工廠:

public class Context

{

Strategy strategy = null;

//調用方法

public void RunMethod(string type)

{

switch (type)

{

default:

case "清蒸":

strategy = new ConcreteStrategyA();

break;

case "紅燒":

strategy = new ConcreteStrategyB();

break;

}

strategy.AlgorithmInterface();

}

}

複制代碼

這樣外部就依賴Context類了:

static void Main(string[] args)

{

Console.WriteLine("我釣了一條魚,應該怎麼煮呢?");

Context context = new Context();

context.RunMethod("清蒸");

context.RunMethod("紅燒");

Console.ReadKey();

}

複制代碼

最後回顧一下:

政策模式不管對象建立,它的目的在于封裝不同的算法,根據傳入的對象,調用具體的政策方法,在上面的示例程式加入簡單工廠模式的原因,是因為要建立對應的具體類,要厘清哪些代碼屬于哪個模式的範疇。

搞了半天,政策模式就是一個類封裝一個算法,實作一個算法接口,然後搞個Context來調用這些算法。