Try   HackMD

虎年行大運 - Design Pattern - Strategy

前言

在生活中,一定都有遇過目的一樣,但過程總會有些許不同的事情。

以買菜這件事情而言,去傳統市場買?去零售超市買?去量販店買?都是買菜,但是過程卻可能不同。

傳統市場和零售超市可能在家附近,量販店可能就要驅車前往。而在價格部份則可能量販店較便宜。

類同上述目的相同、過程不同的事情百百種。程式設計也相同,若完成需求的程式邏輯簡單,那真的也不需要參考設計模式的方式設計,但工程師們就是專門處理複雜問題,化繁為簡的職業。你面對的問題絕不簡單,你必須要學會可以正確切分程式邏輯的設計模式。

今天要介紹的就是 Strategy Pattern

主題

Strategy Pattern

中文常見名稱 策略模式

屬於 Behaviral Patterns 一種,目的是為了封裝演算法,達到流程與演算法的解偶,後續流程可以透過引用不同的演算法物件,取得不同的演算法內容進行需求的處理,並產出相同的結果。

引用上述的買菜例子,我們可封裝三種買菜的過程與方式,而最終都會取到買菜的結果。

使用者專注於結果的取得與後續的處理。專注於業務邏輯層。
開發者則可專注於產生結果的過程與方式。專注於應用模組層。

彼此在工作結構上可以切分得更仔細,專注於各自擅長的領域。

優點:

  • 高度靈活替換實體類別,避免大量使用 If Else
  • 水平擴展容易

缺點:

  • 垂直擴展困難
  • 使用者必須熟知所有策略實體類別


該圖引用來自 Wiki Strategy Pattern - Class Diagram

實行方式

package designPattern.Strategy; /** * @author kaichen * Strategy 模式,將不同的處理行為或邏輯進行封裝,並藉由介面提供接口方法。 * 由外界決定實現的實體 */ public class Strategy { public static void main(String [] args){ InitAbstractStrategy initStrategy = new InitStrategyImpl(); initStrategy.doPay(); InitAbstractStrategy initStrategy2 = new InitStrategyImpl2(); initStrategy2.doPay(); } } interface InitStrategy { public void pay(); public void beforePay(); public void afterPay(); } abstract class InitAbstractStrategy implements InitStrategy { public void doPay(){ beforePay(); pay(); afterPay(); } } class InitStrategyImpl extends InitAbstractStrategy { @Override public void pay() { System.out.println("This is Impl 1 Pay()"); } @Override public void beforePay() { System.out.println("This is Impl 1 beforePay()"); } @Override public void afterPay() { System.out.println("This is Impl 1 afterPay()"); } } class InitStrategyImpl2 extends InitAbstractStrategy { @Override public void pay() { System.out.println("This is Impl 2 Pay()"); } @Override public void beforePay() { System.out.println("This is Impl 2 beforePay()"); } @Override public void afterPay() { System.out.println("This is Impl 2 afterPay()"); } }

在範例中建立 InitStrategy 的介面,並以 InitAbstractStrategy 抽象實作介面後,在抽象建立流程方法,以便流程與方法的解耦合。

隨後建立 InitStrategyImplInitStrategyImpl2 等兩個實體,並繼承抽象 InitAbstractStrategy,實作介面方法。

呼叫時候透過抽象呼叫實體,我們即可直接使用抽象的流程方法,讓介面負責接口、抽象負責流程、實體負責實作。

總結:

  • 介面: 提供接口
  • 抽象: 制定流程
  • 實體: 實作邏輯

以上述這種方式去處理這一次的範例程式結構。

用一句話介紹 Strategy Pattern: 將不同面向的處理模組進行抽出,獨立於流程之外,達到兩者職責分明的設計模式

首頁 Kai 個人技術 Hackmd

tags: Design Pattern