標籤:

設計模式之策略模式

題外話:本文的代碼我放在 Github 上,感興趣的可以去下載使用,在閱讀本文之前希望你熟悉 Java 語法基礎。

定義:定義一系列的演算法,把每一個演算法封裝起來,並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。

類別:行為型模式

舉個例子:

某人從地 A 到地 B 旅行,而旅遊出行的方式有自行車,汽車,火車或飛機。該人無論使用哪種方式都可以到達目的。

在程序設計中,我們在解決元素排序問題的時候有很多種演算法,如:快速排序,堆排序,冒泡排序等等。它們均可以解決元素排序問題,得到的結果是一樣,只是時間效率不同,各有不同的運用場景。

使用策略模式可以將各個演算法封裝起來,那麼在不同場景下可以調用不用的演算法解決相同的問題,從而提高程序的運行效率。

用類圖表示:

  1. 環境類(Context):一個 ConcreteStrategy 對象來配置。維護一個對 Strategy 對象的引用。可定義一個介面來讓 Strategy 訪問它的數據。

  2. 抽象策略類(Strategy):定義所有支持的演算法的公共介面。 Context 使用這個介面來調用某 ConcreteStrategy 定義的演算法。

  3. 具體策略類(ConcreteStrategy):以 Strategy 介面實現某具體演算法。

在以下情況下可以使用策略模式:

  • 如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用策略模式可以動態地讓一個對象在許多行為中選擇一種行為。
  • 一個系統需要動態地在幾種演算法中選擇一種。
  • 不希望客戶端知道複雜的、與演算法相關的數據結構,在具體策略類中封裝演算法和相關的數據結構,提高演算法的保密性與安全性。

同樣的策略模式也暴露了一些缺點:

  1. 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
  2. 策略模式將造成產生很多策略類,可以通過使用享元模式在一定程度上減少對象的數量。

用 Java 代碼表示為:

抽象策略類和具體策略類:

interface IStrategy{n public void doSomething();n}nnclass ConcreteStrategy1 implements IStrategy{n public void doSomething(){ntSystem.out.println("具體策略1");n }n}nnclass ConcreteStrategy2 implements IStrategy{n public void doSomething(){ntSystem.out.println("具體策略2");n }n}n

環境類:

class Context {n private IStrategy strategy;n public Context(IStrategy strategy){ntthis.strategy = strategy;n }nn public void execute(){ntstrategy.doSomething();n }n}n

客戶端調用:

public class Client{n public static void main(String[] args){ntContext context;ntSystem.out.println("-----執行策略1-----");ntcontext = new Context(new ConcreteStrategy1());ntcontext.execute();nntSystem.out.println("-----執行策略2-----");ntcontext = new Context(new ConcreteStrategy2());ntcontext.execute();n }n}n

運行結果:


推薦閱讀:

Lua的好處是什麼以及如何用Lua設計所謂「組件式架構」?
設計模式之七大基本原則
設計模式之單例模式
抽象工廠模式和工廠模式的區別?
敏捷開發中如何保證界面設計?

TAG:设计模式 |