1. 程式人生 > >策略模式:封裝變化與面向介面程式設計

策略模式:封裝變化與面向介面程式設計

摘要:
  
  在使用Java的集合框架中,經常需要通過構造方法傳入一個比較器Comparator或者建立比較器傳入Collections的靜態方法中作為方法引數,進行比較排序等,這其實就是策略模式的應用。策略模式是封裝變化和麵向介面程式設計兩個基本的面向物件設計思想具體應用,其用意是針對一組演算法,將每個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以靈活替換,使得程式具有更好的可擴充套件性和可維護性。策略模式的核心就在於:策略演算法是相同行為的不同實現。

一. 引子

  在Java的集合框架中,經常需要通過構造方法傳入一個比較器Comparator,或者建立比較器傳入Collections的靜態方法中作為方法引數,進行比較排序等,這其實就是策略模式的應用。例如,在陣列工具類 Arrays 存在一個這樣的方法:

public static <T> void sort(T[] a, Comparator<? super T> c)

  該方法旨在根據指定比較器對指定物件陣列進行排序。我們知道,程式設計的基本目標是:將保持不變的事物與會發生改變的事物相分離(封裝變化)。在這裡,不變的是通用的排序演算法,變化的是各種物件相互比較的方式。因此,JDK不是將進行比較的程式碼編寫成不同的子程式,而是借用策略模式進行處理。通過使用策略可以將“會發生變化的程式碼”封裝在單獨的類中(策略物件),你可以將不同的策略物件總是傳遞給相同的程式碼,這些程式碼將使用策略來完成其演算法。

二. 定義與結構

  策略模式屬於物件的行為模式,其用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化。

1、定義

  定義 : 定義一組演算法,將每個演算法都封裝起來,並且使它們之間可以互換。

  策略模式體現的兩個基本的面向物件設計思想:封裝變化 和 面向介面程式設計。

2、結構

  策略模式主要包含三個角色,即 抽象策略角色 、具體策略角色 以及 環境角色,如下圖所示:

  • 抽象策略角色:抽象角色,通常由一個介面或抽象類實現,此角色給出所有的具體策略類所需的介面;

  • 具體策略角色:包裝了相關的演算法和行為;

  • 環境角色:持有一個Strategy的引用。

              image_1c00ln05p2g11clf18vh1jp31kim.png-19.7kB

三. 策略模式的實現

  • 環境角色類
// 客戶端
public class Context {
    //持有一個具體策略的物件
    private Strategy strategy;
    /**
     * 建構函式,傳入一個具體策略物件
     * @param strategy    具體策略物件
     */
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 策略方法
     */
    public void contextInterface(){

        strategy.strategyInterface();
    }

}
  • 抽象策略類
// 抽象策略
public interface Strategy {
    /**
     * 策略方法
     */
    public void strategyInterface();
}
  • 具體策略類
// 具體策略 A
public class ConcreteStrategyA implements Strategy {
    @Override
    public void strategyInterface() {
        //相關的業務
    }
}
// 具體策略 B
public class ConcreteStrategyB implements Strategy {
    @Override
    public void strategyInterface() {
        //相關的業務
    }
}
// 具體策略 C
public class ConcreteStrategyC implements Strategy {
    @Override
    public void strategyInterface() {
        //相關的業務
    }
}

四. 總結

1、策略模式的特徵

  策略模式的重心 : 策略模式的重心不是如何實現演算法,而是如何組織、呼叫這些演算法,從而讓程式結構更靈活,具有更好的維護性和擴充套件性;

  演算法的平等性 : 策略模式一個很大的特點就是各個策略演算法的平等性。對於一系列具體的策略演算法,大家的地位是完全一樣的,正因為這個平等性,才能實現演算法之間可以相互替換。所有的策略演算法在實現上也是相互獨立的,相互之間是沒有依賴的。所以,可以這樣描述這一系列策略演算法:策略演算法是相同行為的不同實現

  執行時策略的唯一性 : 執行期間,策略模式在每一個時刻只能使用一個具體的策略實現物件,雖然可以動態地在不同的策略實現中切換,但是同時只能使用一個;

  公有的行為 : 經常見到的是,所有的具體策略類都有一些公有的行為。這時候,就應當把這些公有的行為放到共同的抽象策略角色 Strategy 類裡面。當然這時候抽象策略角色必須要用Java抽象類實現,而不能使用介面(Java 1.8 以後允許介面中有預設方法)。

2、策略模式的優點

  (1). 策略模式提供了管理相關的演算法族的辦法,策略類的等級結構定義了一個演算法或行為族。恰當使用繼承可以把公共的程式碼移到父類裡面,從而避免程式碼重複。

  (2). 使用策略模式可以避免使用多重條件(if-else)語句。多重條件語句不易維護,它把採取哪一種演算法或採取哪一種行為的邏輯與演算法或行為的邏輯混合在一起,統統列在一個多重條件語句裡面,比使用繼承的辦法還要原始和落後。

3、策略模式的缺點

  (1). 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味著客戶端必須瞭解這些演算法的區別,以便適時選擇恰當的演算法類。換言之,策略模式只適用於客戶端知道演算法或行為的情況。

  (2). 由於策略模式把每個具體的策略實現都單獨封裝成為類,如果備選的策略很多的話,那麼物件的數目就會很可觀。

引用:

相關推薦

策略模式封裝變化面向介面程式設計

摘要:      在使用Java的集合框架中,經常需要通過構造方法傳入一個比較器Comparator或者建立比較器傳入Collections的靜態方法中作為方法引數,進行比較排序等,這其實就是策略模式的應用。策略模式是封裝變化和麵向介面程式設計兩個基本的面向

vc進行office(word)程式設計之一開啟vcoffice介面程式設計的大門

第一步:將word的介面類匯入進來 如果是vc6.0 1、點View選單中的ClassWizard(或按CTRL+W) 2. 選擇Automation標籤,點Add Class並選擇"From a type library" 瀏覽並選擇你希望自動化的物件庫(例如,如果你自動

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

簡單工廠,真的是特別簡單的一個設計模式。 工廠方法內定義需要用到的方法的父類, 根據傳遞的引數來決定例項化何種子類物件。 //演算法的父類,抽象出返回結果的介面 public interface

工廠模式工廠方法抽象工廠的戰爭

概述 什麼是工廠方法?什麼是抽象工廠? 工廠方法是指工廠生產產品,而抽象工廠是生產產品系列。例如,工廠方法是隻生產運輸工具比如馬車、公共汽車、自行車,而抽象工廠生產輪胎、螺絲釘交通工具零件。 工廠方法模式定義了一個建立物件的介面,但由子類決定例項化的類是哪一個。工廠方法讓類把例項化推

策略模式會員卡功能

老闆發話了,這個季度要做 會員卡功能,我先來做做功課。 前言   上面這張圖是京東商城的會員體系,總共包含五種不同等級的會員,分別是註冊會員,銅牌會員,銀牌會員,黃金會員,鑽石會員。從上圖可以看出,不同等級會員享有不同的優惠服務,那麼這麼多優惠服務在程式中是怎麼實現的

C語言面向物件程式設計面向介面程式設計(4)

 Java 中有 interface 關鍵字,C++ 中有抽象類或純虛類可以與 interface 比擬,C 語言中也可以實現類似的特性。     在面試 Java 程式設計師時我經常問的一個問題是:介面和抽象類有什麼區別。  &n

STM32串列埠2種通訊模式非同步通訊同步通訊

目錄 3.非同步通訊 1.特點 4.同步通訊 1.特點  傳送資料暫存器TDR和傳送移位暫存器:傳送暫存器用來儲存要傳送的資料,一位暫存器用來將資料從LSB一位一位地移出去  接收資料暫存器RDR和接收移位暫存器:接受資料移位暫存器將資料從L

mybatis面向介面程式設計實踐mapper代理物件的產生

上篇提到面向介面程式設計需要使用getMapper獲取代理物件,今天我們來看一下mapper代理物件是如何產生的,在此之前先回憶下面試介面程式設計。 一、Mybatis面向介面程式設計實踐 (一)使用xml的方式 1.定義mapper介面 Mapper介面就是一

C#進階系列——MEF實現設計上的“鬆耦合”(終結篇面向介面程式設計

序:忙碌多事的八月帶著些許的倦意早已步入尾聲,金秋九月承載著抗戰勝利70週年的喜慶撲面而來。沒來得及任何準備,似乎也不需要任何準備,因為生活不需要太多將來時。每天忙著上班、加班、白加班,忘了去憤,忘了去算計所謂的價值。天津爆炸事故時刻警示著我們生命的無常,逝者安息,活著的人生活還得繼續,珍惜生命,遠離傷害。武

android面向介面程式設計(抽象工廠模式,擴充套件性超強,Demo優化)

本分開始之前。咱先提出來幾個疑問: 介面有什麼用途? 面向介面程式設計的好處? 它和抽象類有什麼區別? 能不能用抽象類代替介面呢? 它和麵向物件程式設計是什麼關係? 本分主要分為: 1.面向介面程式設計和麵向物件程式設計是什麼關係? 2.介面

設計模式可複用面向物件軟體的基礎【pdf下載】

放心下載pdf地址:必看理由:這是一本設計模式領域的經典書籍,傳說中的四人幫(GoF)的作品,久經時間考驗,值得一看再看。豆瓣評分:9.1 美國亞馬遜評分:4.5網友評論:(亞馬遜網友)這是一本設計模式領域的經典的書籍。對於初學者來說,最好先看一本設計模式入門的書後(比如He

初學Java 面向介面程式設計 命令模式 十八

                命令模式 :把一個請求或者操作封裝到一個物件中。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的物件。命令模式允許請求的一方和傳送的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求是怎麼被接收,以及操作是否執行,何時被執行以及是怎麼被執行的。

好書整理系列之-設計模式可複用面向物件軟體的基礎 4

第4章結構型模式結構型模式涉及到如何組合類和物件以獲得更大的結構。結構型類模式採用繼承機制來組合介面或實現。一個簡單的例子是採用多重繼承方法將兩個以上的類組合成一個類,結果這個類包含了所有父類的性質。這一模式尤其有助於多個獨立開發的類庫協同工作。另外一個例子是類形式的A d

C語言面向物件程式設計(四)面向介面程式設計

    Java 中有 interface 關鍵字,C++ 中有抽象類或純虛類可以與 interface 比擬,C 語言中也可以實現類似的特性。     在面試 Java 程式設計師時我經常問的一個問題是:介面和抽象類有什麼區別。     很多程式設計書籍也經常說要面向介面

好書整理系列之-設計模式可複用面向物件軟體的基礎 3

第3章建立型模式建立型模式抽象了例項化過程。它們幫助一個系統獨立於如何建立、組合和表示它的那些物件。一個類建立型模式使用繼承改變被例項化的類,而一個物件建立型模式將例項化委託給另一個物件。隨著系統演化得越來越依賴於物件複合而不是類繼承,建立型模式變得更為重要。當這種情況發生時

面向介面程式設計 多型 通俗易懂的解釋(轉載自知乎)

說“空話”,做實事: 談談多型 原出處 劉欣公眾號 碼農翻身 最近有初學者問多型有什麼用, 思考了一下,就有了這篇文章。 1 什麼是多型? 多型是碼農們必須要理解理解的一個基本思想, 是面向物件的基石。 但是很多人(包括我)第一次接觸多型時都會困惑: 這

工廠模式封裝物件的建立(一、在基類中定義一個靜態成員函式)

當我們發現需要新增新的型別到一個系統中時,最明智的首要步驟就是用多型機制為這些新型別建立一個共同的介面。 用這種方法可以將系統中多餘的程式碼與新新增的特定型別的程式碼分開。新型別的新增並不會攪亂已存在的程式碼...或者至少看上去如此。 起初它似乎只需要在繼承新類的地方修改程

好書整理系列之-設計模式可複用面向物件軟體的基礎 6

第6章結論或許有人會認為本書並多大貢獻。畢竟,它沒有提出任何前所未見的新演算法或者新程式設計技術。本書既沒有給出一種嚴格的系統設計方法,也沒有提出一套新的設計理論-它只是將現有的一些設計加以文件化。也許你會認為它是一本合適的入門指南,但對有經驗的面向物件設計人員卻並無多大幫助

面向介面程式設計詳解(三)——模式研究

通過前面兩篇,我想各位朋友對“面向介面程式設計”的思想有了一定認識,並通過第二篇的例子,獲得了一定的直觀印象。但是,第二篇中的例子旨在展示面向介面程式設計的實現方法,比較簡單,不能體現出面向介面程式設計的優勢和這種思想的內涵。那麼,這一篇作為本系列的終結篇,將通過分析幾個比較

工廠模式封裝物件的建立(二、多型工廠)

在上篇中,靜態成員函式  static Shape* factory(const string& type) 迫使所有建立物件的操作都集中在一個地方, 因此這個地方就是唯一需要修改程式碼的地方。這是一個合理的決解方法,因為它完美的封裝了物件的建立過程。 但是工廠方法