設計模式之--策略模式及其在JDK中的應用

weixin_34236497發表於2018-09-10

前言:本文主要介紹設計模式中的策略模式,準備按照以下幾個方面展開:

  • 什麼是策略模式
  • 策略模式結構和UML圖
  • 策略模式在JDK中的應用

一、什麼是策略模式以及策略模式功能

1.1 為什麼需要策略模式?

1)完成一項任務,往往可以有多種不同的方式,每一種方式稱為一個策略,我們可以根據環境或者條件的不同選擇不同的策略來完成該項任務。
2)在軟體系統中,很多演算法可以實現某一功能,比如查詢、排序。這裡以查詢演算法為例說明,如果我們需要提供多種查詢演算法,可以將這些演算法寫在一個類中,在該類中提供多個方法,每一個方法對應一個具體的查詢演算法;當然也可以將這些查詢演算法封裝在一個統一的方法中,通過if…else…等條件判斷語句來進行選擇。但是這兩種實現方式有個弊端,如果需要增加一種新的查詢演算法,需要修改封裝演算法類的原始碼;更換查詢演算法,也需要修改客戶端呼叫程式碼。維護起來比較困難。
3)除了提供專門的查詢演算法類之外,還可以在客戶端程式中直接包含演算法程式碼,這種做法更不可取,將導致客戶端程式龐大而且難以維護,如果存在大量可供選擇的演算法時問題將變得更加嚴重。(這裡的在客戶端中包含演算法程式碼的意思就好比我們在包含main函式的類裡去實現演算法,而不專門提供封裝演算法的類)
4)為了解決這些問題,可以定義一些獨立的類來封裝不同的演算法,每一個類封裝一個具體的演算法,在這裡,每一個封裝演算法的類我們都可以稱之為策略(Strategy),為了保證這些策略的一致性,一般會用一個抽象的策略類來做演算法的定義,而具體每種演算法則對應於一個具體策略類。

1.2 什麼是策略模式?

策略模式(Strategy Pattern):定義一系列演算法,將每一個演算法封裝起來,並讓它們可以相互替換。策略模式讓演算法獨立於使用它的客戶而變化。

二、策略模式結構和UML圖

2.1 策略模式結構

策略模式包含如下角色:

  • Context: 環境類
  • Strategy: 抽象策略類
  • ConcreteStrategy: 具體策略類

其中Context類持有Strategy的引用,ConcreteStrategy實現Strategy介面。

2.2 策略模式UML圖

5679451-aac3c66b8f763ef0.png
image.png

2.3 策略模式Demo

以上面說的排序演算法的選擇為例,寫一個Demo。

首先定義抽象策略類AbstractSort


public interface AbstractSort {
    void sort();
}

然後定義具體策略類ConcreteSort1,ConcreteSort2,ConcreteSort3


public class ConcreteSort1 implements AbstractSort {

    @Override
    public void sort() {
        System.out.println("使用快速排序");
    }

}

public class ConcreteSort2 implements AbstractSort {

    @Override
    public void sort() {
        System.out.println("使用歸併排序");
    }

}

public class ConcreteSort3 implements AbstractSort {

    @Override
    public void sort() {
        System.out.println("使用堆排序");
    }

}

接著定義Context環境類


public class Context {

    public AbstractSort method;

    public Context(AbstractSort abstractSort) {
        this.method = abstractSort;
    }

    public void contextSort() {
        method.sort();
    }
}

最後定義客戶端類Main


public class Main {

    public static void main(String[] args) {
        //傳入不同的具體策略即可
        Context context = new Context(new ConcreteSort2());
        context.contextSort();

    }

}

三、策略模式在JDK中的應用

3.1 比較器Comparator

     在Java的集合框架中,經常需要通過構造方法傳入一個比較器Comparator,或者建立比較器傳入Collections的靜態方法中作為方法引數,進行比較排序等,使用的是策略模式。

     在該比較架構中,Comparator就是一個抽象的策略;一個類實現該結構,並實現裡面的compare方法,該類成為具體策略類;Collections類就是環境角色,他將集合的比較封裝成靜態方法對外提供api。

3.2 ThreadPoolExecutor中的四種拒絕策略

     在建立執行緒池時,需要傳入拒絕策略,當建立新執行緒使當前執行的執行緒數超過maximumPoolSize時,將會使用傳入的拒絕策略進行處理。

  • AbortPolicy:直接丟擲異常。
  • CallerRunsPolicy:只用呼叫者所線上程來執行任務。
  • DiscardOldestPolicy:丟棄佇列裡最近的一個任務,並執行當前任務。
  • DiscardPolicy:不處理,丟棄掉。

     這裡使用的就是策略模式。

相關文章