成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

徹底搞懂策略設計模式

開發 前端
什么是策略呢?所謂策略,你可以理解它就是?一組算法或實現方法的組合。我們知道,實現某個功能的方法可能有很多。如果我們把這些方法封裝起來,并能夠確保它們可以相互替換,那么就可以構建出一系列的實現策略,這就是策略模式的由來。

對于任何一個軟件系統而言,從組成結構上通常可以分成兩大部分,內核組件和擴展組件。我們知道,內核組件是需要非常穩定的,而擴展組件則應該按需開發,動態替換。

內核和擴展結構示意圖內核和擴展結構示意圖

顯然,想要實現這張圖中的效果,我們需要對擴展組件進行抽象。

基于這種抽象,就可以實現不同的擴展組件。而因為這些擴展組件都是抽象組件的具體實現,所以它們可以相互替換。

抽象組件和擴展組件之間的關系抽象組件和擴展組件之間的關系

其實想要實現圖中的這種效果,我們有很多種方法。在面向對象的世界中,我們可以引入一種專門的設計模式來做到這一點,這種設計模式就是我們今天要講的策略模式。

策略模式的基本概念和簡單示例

那么,什么是策略呢?所謂策略,你可以理解它就是 一組算法或實現方法的組合。我們知道,實現某個功能的方法可能有很多。如果我們把這些方法封裝起來,并能夠確保它們可以相互替換,那么就可以構建出一系列的實現策略,這就是策略模式的由來。這個模式的結構可以這樣表示:

策略模式的結構示意圖策略模式的結構示意圖

這張圖中,可以看到,Strategy 是一個公共接口,代表對具體實現方法的抽象。而 ConcreteStrategyA 和 ConcreteStrategyB 分別是 Strategy 接口的兩個實現類,代表了不同的實現方法。同時,我們還注意到,這里有一個上下文組件 Context,來保持對 Strategy 接口的引用。

顯然,我們可以把這里的 Context 看作是內核組件,而 Strategy 接口以及兩個 ConcreteStrategy 實現類分別看作抽象組件和擴展組件。

前面已經提到,在面向對象的世界中,我們通常使用接口來定義一種策略。例如,在這個 Strategy 接口中,我們定義了一個方法,這個方法可以用來對輸入的兩個數字執行某一個操作。

public interface Strategy {
   public int execute(int num1, int num2);
}

然后,我們就可以基于這個 Strategy 接口,來實現對這兩個數字的具體計算方法。這里列舉了常見的加法、減法和乘法。

public class AdditionStrategy implements Strategy{
   @Override
   public int execute(int num1, int num2) {
      return num1+ num2;
   }
}
publicclass SubtractionStrategy implements Strategy{
   @Override
   public int execute(int num1, int num2) {
      return num1- num2;
   }
}
publicclass MultiplicationStrategy implements Strategy{
   @Override
   public int execute(int num1, int num2) {
      return num1* num2;
   }
}

這些算法都非常簡單,而對應的 Context 類也并不復雜。我們在這個類中注入了一個 Strategy 接口,然后通過這個接口的 execute 方法,來執行具體的計算方法。

public class Context {
   private Strategy strategy;
   public Context(Strategy strategy){
      this.strategy = strategy;
   }
   public int performCalculation(int num1, int num2){
      return strategy.execute(num1, num2);
   }
}

針對上面 Context,我們也可以編寫對應的測試類。

public class StrategyTest {
   public static void main(String[] args) {
      Context context1= new Context(new AdditionStrategy());
      System.out.println(context.executeStrategy(1, 1));
      Context context2 = new Context(new SubtractionStrategy());
      System.out.println( context.executeStrategy(1, 1));
      Context context3 = new Context(new MultiplicationStrategy());
      System.out.println(context3.executeStrategy(1, 1));
   }
}

顯然,策略模式本身的實現方式非常清晰。但在日常開發過程中,我們很少碰到像上面的代碼示例這樣簡單的應用場景。這時候,就需要我們理解策略模式的本質作用,從繁冗復雜的代碼結構中識別出策略模式的應用方式,從而更好地把握代碼的結構。

策略模式在主流開源框架中可以說應用非常廣泛。接下來,我們就以 MyBatis 框架為例,來分析一下它的應用場景和實現過程。

策略模式在 MyBatis 中的應用與實現

在 MyBatis 中,策略模式的應用場景主要就在 SQL 的執行器組件——Executor 中。作為 MyBatis 中最核心的接口之一,Executor 接口定義的內容非常豐富,這里列舉幾個比較有代表性的方法:

public interface Executor {
//執行 update、insert、delete 三種類型的 SQL 語句
int update(MappedStatement ms, Object parameter) throws SQLException;
//執行 selete 類型的 SQL 語句,返回值分為結果對象列表或游標對象
  <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
 ...
//批量執行 SQL 語句
List<BatchResult> flushStatements() throws SQLException;
//提交事務
void commit(boolean required) throws SQLException;
//回滾事務
void rollback(boolean required) throws SQLException;
}

在上面代碼中,我們看到了一組用來實現數據庫訪問的常用方法,包括用于執行查詢的 query 方法、用于執行更新的 update 方法、用于提交和回滾事務的 commit 和 rollback 方法,以及用于執行批量 SQL 的 flushStatements 方法。

在 MyBatis 中,Executor 接口具有一批實現類。

MyBatis 中 Executor 接口的類層結構圖MyBatis 中 Executor 接口的類層結構圖

  • SimpleExecutor:普通執行器
    這是 MyBatis 中最基礎的、也是默認使用的一種 Executor,封裝了對基本 SQL 語句的各種操作。
  • ReuseExecutor:重用執行器
    顧名思義,這種 Executor 提供了對 SQL 語句進行重復利用的功能特性。基于這種功能特性,SQL 語句的創建、銷毀以及預編譯過程會得到優化,從而降低資源消耗,提高性能。
  • BatchExecutor:批處理執行器
    從命名上,我們也不難看出,這種 Executor 的作用就是完成對 SQL 語句的批量處理。批處理的優勢同樣是節省資源消耗,因為我們可以一次向數據庫發送多條 SQL 語句。

顯然,這三個 Executor 實現類就是對 Executor 的不同策略實現。明確了這一點之后,我們接下來還需要明確兩個問題,也就是:

  • 這些具體策略實現類是如何生成的呢?
  • 在 MyBatis 中,哪個組件扮演了 Context 角色呢?

我們先來看第一個問題。在 MyBatis 的配置文件中存在一個配置項,這個配置項用于設置 Executor 的默認類型。正如上面所討論的,這個配置項指定了 MyBatis 默認采用的 Executor 是 SimpleExecutor。

<setting name="defaultExecutorType" value="SIMPLE" />

那么,Executor 是從哪里創建出來的呢?這就涉及到 MyBatis 中與配置相關的 Configuration 類。Configuration 是一種門面類,但也扮演著工廠類的角色,能夠根據傳入的策略類型來生成具體的策略對象。

protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
public Executor newExecutor(Transaction transaction) {
    return newExecutor(transaction, defaultExecutorType);
}
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } elseif (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    ...
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
}

可以看到,這里通過 Executor 的類型——ExecutorType,來決定構建哪一種具體的 Executor 實現類。請注意,我們在這里看到了一個 interceptorChain 對象,這是 MyBatis 中的攔截器組件,體現的是一種責任鏈處理機制。

接下來,我們討論第二個問題,就是在 MyBatis 中,哪個組件扮演了 Context 角色呢?答案是 DefaultSqlSession。

DefaultSqlSession 內部包含了對 Executor 的引用,而 DefaultSqlSession 是通過 SqlSessionFactory 接口的默認實現類——DefaultSqlSessionFactory 進行構建的。在 SqlSession 生成過程中,需要指定 ExecutorType。這時就會調用 Configuration 對象的這個 newExecutor 方法。

DefaultSqlSession 相關類層結構圖DefaultSqlSession 相關類層結構圖

在具體實現過程中,策略模式也可以和其他設計模式組合在一起使用。例如,MyBatis 針對 Executor 的設計,同時使用了模板方法模式和策略模式。來看一下整合了模板方法模式和策略模式的類層結構圖。

Executor 接口完整類層結構圖Executor 接口完整類層結構圖

總的來說,針對 SQL 執行過程,我們知道 MyBatis 分別提供了 SimpleExecutor、ReuseExecutor 以及 BatchExecutor 這三種不同的實現策略。這三種 Executor 都有一個共同的父類——BaseExecutor,在這個類中定義了一組抽象方法,交由它的三個子類進行實現,這種實現方式就是典型的模板方法設計模式。實際工作中,策略模式和模板方法模式也是一種常見的組合模式。

總結

最后我來給你總結一下。

圖片圖片

如果你正在考慮圍繞一個業務場景提供不同的實現方法,那么可以先停下來,分析一下業務場景是否可以使用策略模式進行實現。如果這些不同的實現方法體現的是算法之間的區別,而不是執行流程上的差異,我們就可以引入今天所介紹的策略模式,并對其進行設計。策略模式是一種非常有用的設計模式,我們也通過基本的實現代碼示例給出了它的實現方法。

就實現方法而言,采用策略模式的第一步,是設計一個合理的策略接口。然后基于不同算法,為這個接口提供不同的實現類。一旦構建了多個實現類之后,我們就可以針對具體場景,選擇具體的實現類,或者提供新的實現類。策略模式能確保這些實現類之間相互獨立,并可以做到靈活替換。

責任編輯:武曉燕 來源: 程序員技術充電站
相關推薦

2024-01-29 12:22:07

設計模式策略模式

2023-05-22 13:27:17

2025-04-21 00:50:50

2020-07-02 09:15:59

Netty內存RPC

2013-11-26 16:09:34

Android設計模式

2021-06-09 08:53:34

設計模式策略模式工廠模式

2015-09-08 13:39:10

JavaScript設計模式

2024-02-26 11:52:38

代理模式設計

2024-02-19 13:11:38

門面模式系統

2017-12-05 17:44:31

機器學習CNN卷積層

2020-10-14 08:50:38

搞懂 Netty 線程

2025-05-06 01:14:00

系統編程響應式

2024-01-30 13:15:00

設計模式責任鏈

2024-02-21 12:24:33

模板設計模式框架

2024-02-23 12:11:53

裝飾器模式對象

2025-04-21 04:00:00

2024-10-06 12:56:36

Golang策略設計模式

2017-07-07 10:55:14

數據庫MongoDB設計模式

2024-02-04 12:04:17

2024-02-27 11:59:12

享元模式對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美一区二区三区免费看 | 在线观看h视频 | 久久久久国产一区二区三区不卡 | 亚洲精品成人网 | www312aⅴ欧美在线看 | 久久毛片| 亚洲精选一区二区 | 天天操夜夜艹 | 91免费看片| 成人国产一区二区三区精品麻豆 | 中文字幕欧美一区 | 亚洲精品一区二区三区在线 | 国产 日韩 欧美 在线 | 亚洲婷婷六月天 | 久草视频观看 | 久久久精品一区二区三区 | 视频在线观看一区二区 | 亚洲国产一区二区三区, | 成人一区二区三区在线观看 | 狠狠干av | 国产色片 | av中文在线播放 | 成人在线免费视频观看 | 久久免费精品视频 | 91精品国产欧美一区二区 | 久久精品视频一区二区 | 国产精品成人一区二区三区 | 欧产日产国产精品99 | 久久精品 | 亚洲欧美成人 | 色视频欧美 | 日本三级网站在线观看 | 日本不卡免费新一二三区 | 亚洲国产精品一区二区久久 | 午夜精品在线观看 | 天天成人综合网 | 欧美一区永久视频免费观看 | 手机av在线 | 国产一区二区久久 | 国产农村妇女精品一二区 | 国产精品国产三级国产a |