簡介 策略模式(Strategy Pattern)屬於行為型設計模式。將每一個演算法封裝到具有共同介面的獨立類中,根據需要來綁定策略,使得具體實現和策略解耦。 當你想使用對象中各種不同的演算法變體,使用if...else 所帶來的複雜和難以維護,可使用策略模式。或者當有許多相同類,它們僅在執行某些行為時 ...
簡介
策略模式(Strategy Pattern)屬於行為型設計模式。將每一個演算法封裝到具有共同介面的獨立類中,根據需要來綁定策略,使得具體實現和策略解耦。
當你想使用對象中各種不同的演算法變體,使用if...else 所帶來的複雜和難以維護,可使用策略模式。或者當有許多相同類,它們僅在執行某些行為時略有不同,可使用策略模式。
作用
- 策略演算法可以自由切換,保持策略與執行類的松耦合。
- 避免使用多重條件判斷,不同環境角色可以組裝多個策略。
- 擴展性良好,可以隨時增刪策略行為。
- 體現了多用組合,少用繼承。
實現步驟
- 建立一個策略介面。
- 新建多個策略行為類,實現該策略介面。
- 建立一個抽象環境角色類,並將策略介面組合進來。是否需要抽象類可選。
- 建立多個環境角色類來繼承該抽象類。
- 可以動態改變環境角色的策略行為。
不同語言設計模式源碼下載:
UML
Java代碼
狀態基礎介面
// Strategy.java 基礎策略介面
public interface Strategy {
public void run();
}
策略實現類
// StrategyA.java 策略A
public class StrategyA implements Strategy {
@Override
public void run() {
System.out.println("StrategyA::run().");
}
}
// StrategyB.java 策略B
public class StrategyB implements Strategy {
@Override
public void run() {
System.out.println("StrategyB::run().");
}
}
// StrategyC.java 策略C
public class StrategyC implements Strategy {
@Override
public void run() {
System.out.println("StrategyC::run().");
}
}
抽象業務類
// Context.java 抽象業務類,聚合策略對象
public abstract class Context {
protected Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void action() {
this.strategy.run();
}
}
具體業務類
// ContextCat.java 業務類構造器聚合了某策略
public class ContextCat extends Context {
public ContextCat() {
// 使用某個策略
System.out.println("ContextCat::setStrategy(StrategyC).");
this.setStrategy(new StrategyC());
}
}
// ContextDog.java 業務類構造器聚合了某策略
public class ContextDog extends Context {
public ContextDog() {
// 使用某個策略
System.out.println("ContextDog::setStrategy(StrategyB).");
this.setStrategy(new StrategyB());
}
}
測試調用
/**
* 策略模式就是根據需要給對象綁定具體策略,使得具體實現和策略可以靈活搭配。
* 先聲明某個具體Context對象,該對象已經綁定了具體策略,同時還可以更改策略。
*/
// 實例化某個內容,策略已經綁定上
Context contextCat = new ContextCat();
contextCat.action();
// 重新設置策略
System.out.println("reset contextCat'strategy to StrategyA.");
contextCat.setStrategy(new StrategyA());
contextCat.action();
// 實例化某個內容,策略已經綁定上
Context contextGog = new ContextDog();
contextGog.action();
Go代碼
狀態基礎介面
// Strategy.go 基礎策略介面
// 定義一個策略介面,註意go語言數據類型即介面
type Strategy interface {
Run()
}
// 寫在介面文件的其他全局方法
func Init() {
fmt.Println("strategy init!")
}
策略實現類
// StrategyA.go 策略A
type StrategyA struct {
}
// 實現策略介面的對應方法
func (s *StrategyA) Run() {
fmt.Println("StrategyA::Run")
}
// StrategyB.go 策略B
type StrategyB struct {
}
// 實現策略介面的對應方法
func (s *StrategyB) Run() {
fmt.Println("StrategyB::Run")
}
// StrategyC.go 策略C
type StrategyC struct {
}
// 實現策略介面的對應方法
func (s *StrategyC) Run() {
fmt.Println("StrategyC::Run")
}
抽象業務類
// Context.go 抽象業務類,聚合策略對象
type Context struct {
strategy Strategy
}
// 設置不同strategy,方法名首字母大寫
func (c *Context) SetStrategy(s Strategy) {
c.strategy = s
}
// 執行策略介面裡面的方法
func (c *Context) Run() {
c.strategy.Run()
}
具體業務類
// ContextCat.go 業務類構造器聚合了某策略
// 定義具體執行對象,Go沒有繼承,用聚合來調用Context里的函數
type ContextCat struct {
context Context
}
// 可提前綁定具體的策略
func (c *ContextCat) Init() {
c.context.SetStrategy(&StrategyC{})
fmt.Println("ContextCat::init. setStrategy(StrategyC)")
}
// 調用策略方法
func (c *ContextCat) Run() {
fmt.Println("ContextCat::run")
c.context.Run()
}
// ContextDog.go 業務類構造器聚合了某策略
type ContextDog struct {
context Context
}
// 可提前綁定具體的策略
func (c *ContextDog) Init() {
c.context.SetStrategy(&StrategyB{})
fmt.Println("ContextDog::init. setStrategy(StrategyB)")
}
// 調用策略方法
func (c *ContextDog) Run() {
fmt.Println("ContextDog::run")
c.context.Run()
}
測試調用
func main() {
fmt.Println("test start:")
// 這裡src.Init來自strategy.go文件
src.Init()
/**
* 策略模式就是根據需要給對象綁定具體策略,使得具體實現和策略可以靈活搭配。
* 先聲明某個具體Context對象,該對象已經綁定了具體策略,同時還可以更改策略。
*/
// 聲明策略執行對象
context := src.Context{}
// 設置策略A
context.SetStrategy(&src.StrategyA{})
// 執行策略A,列印StrategyA
context.Run()
// 設置策略B
context.SetStrategy(&src.StrategyB{})
// 執行策略B,列印StrategyB
context.Run()
// 執行策略C,列印StrategyC
context.SetStrategy(&src.StrategyC{})
context.Run()
// /*********************** 分割線 ******************************************/
// 直接實例化具體執行對象,策略已經綁定
contextCat := src.ContextCat{}
contextCat.Init()
contextCat.Run()
// 直接實例化具體執行對象,策略已經綁定
contextDog := src.ContextDog{}
contextDog.Init()
contextDog.Run()
}
更多語言版本
不同語言設計模式源碼:https://github.com/microwind/design-pattern