1. 程式人生 > >深入探索Java設計模式(二)之策略模式

深入探索Java設計模式(二)之策略模式

策略設計模式是Java API庫中常見的模式之一。這與另一個設計模式(稱為狀態設計模式)非常相似。本文是在學習完優銳課JAVA架構VIP課程—【框架原始碼專題】中《學習原始碼中的優秀設計模式》後寫下的學習感悟。簡要介紹了該思想,並提供了有關如何在Java中實現該思想的示例。

深入探索Java設計模式(一)之單例模式

 

總覽

策略模式也稱為策略模式。它被歸類為行為軟體設計模式,其中重點是在物件之間找到靈活的通訊模式。它有助於在執行時物件之間建立靈活的通訊。

 

策略模式

策略模式的基本思想是在類的較小層次擴充套件中組合一組操作。與該策略相關的物件確定在給定情況下將使用哪種演算法。例如,它使我們能夠在執行時交換演算法的實現細節,而無需我們重寫它。這個想法與依賴注入中的實現模式產生了共鳴,因為它還允許在測試過程中將實現換出,例如在測試程式碼中執行模擬實現。

從狀態設計模式的角度來看,它類似於狀態設計模式,它是封裝上下文物件狀態的物件。策略設計模式中的物件類似地封裝了演算法的實現,並且可以根據需要在執行時交換事件。

在Java API庫中,java.awt.Container元件是使用此模式的示例。此處,LayoutManager充當策略物件。這些類(例如BorderLayout,FlowLayout和GridLayout)實現介面LayoutManager。實現的類定義一個名為addLayoutComponent()的方法。此方法內的定義確定邏輯,或如何將元件佈置在Container物件中。例如,FlowLayout從左到右放置它們,而BorderLayout將它們放置在名為CENTER,NORTH,EAST,SOUTH,WEST的區域中。 Container類包含稱為LayoutManager物件的策略物件。因為該介面包含對實現該介面的類的物件的引用,所以策略物件可以隨時引用已實現的類。

 

策略模式的使用

它基本上是從通用基類繼承的類的集合。它具有相同的基本結構和通用功能,但區別在於使用方式。可以說,它按照所應用的策略起作用。策略模式通過提供執行時靈活性來增強你的能力。與其他類似的模式(例如狀態和命令)不同,可以通過建立代理類來利用這種靈活性,該代理類在執行時控制特定策略的選擇。

 

實現策略模式

這是此模式的快速實現。這個想法很簡單,但是可以有效地選擇所需的實現並根據需要進行交換。沒什麼好想的,類的介面和層次結構建立了演繹,這是在程式碼中使用的一種策略。

在這裡,它使我們能夠使用Sort介面編寫程式碼,而我們想要排序的程式碼不必關心用於排序的演算法。通過對介面和適合特定實現的類結構進行程式設計,我們可以根據需要使用介面,並在需要其他介面時立即更改策略。從某種意義上說,這個想法是可擴充套件的,在以後,我們可以新增更多的實現。針對該介面編寫的任何程式碼都不會更改,但可以使用新的實現。

 1 package org.mano.example;
 2 public interface Sort {
 3    int [] sort(int[] nos);
 4 }
 5 package org.mano.example;
 6 public class BubbleSort implements Sort{
 7    @Override
 8    public int [] sort(int[] nos) {
 9       System.out.println("\n--- BUBBLE SORT strategy
10          in action---\n");
11       int n = nos.length;
12       for (int i = 0; i < n-1; i++)
13       for (int j = 0; j < n-i-1; j++)
14       if (nos[j] > nos[j+1])
15       {
16          int tmp = nos[j];
17          nos[j] = nos[j+1];
18          nos[j+1] = tmp;
19       }
20       return nos;
21    }
22 }
23 package org.mano.example;
24 public class SelectionSort implements Sort{
25    @Override
26    public int [] sort(int [] nos) {
27       System.out.println("\n--- SELECTION SORT strategy
28          in action ---\n");
29       int n = nos.length;
30       for (int i = 0; i < n-1; i++)
31       {
32          int mindex = i;
33          for (int j = i+1; j < n; j++)
34             if (nos[j] < nos[mindex])
35                mindex = j;
36          int temp = nos[mindex];
37          nos[mindex] = nos[i];
38          nos[i] = temp;
39       }
40       return nos;
41    }
42 }
43 package org.mano.example;
44 public class ShellSort implements Sort {
45    @Override
46    public int [] sort(int[] nos) {
47       System.out.println("\n--- SHELL SORT strategy
48          in action ---\n");
49       int n = nos.length;
50       for (int part = n/2; part > 0; part /= 2)
51       {
52          for (int i = part; i < n; i += 1)
53          {
54             int temp = nos[i];
55             int j;
56             for (j = i; j >= part && nos[j - part] >
57                temp; j -= part) nos[j] = nos[j - part];
58             nos[j] = temp;
59          }
60       }
61       return nos;
62    }
63 }
64 package org.mano.example;
65 import java.util.Random;
66 public class SortingApp {
67    private Sort sortStrategy;
68    public SortingApp(Sort sort){
69       this.sortStrategy = sort;
70    }
71    public int [] sort(int[] data){
72       return sortStrategy.sort(data);
73    }
74    public void changeStrategy(Sort anotherStrategy){
75       sortStrategy = anotherStrategy;
76    }
77    public void printArray(int arr[])
78    {
79       int n = arr.length;
80       for (int i=0; i<n; ++i)
81          System.out.print(arr[i]+" ");
82       System.out.println();
83    }
84    public static int [] getDummyData(){
85       Random r = new Random();
86       int [] data = new int [10];
87       for (int i=0;i<10;i++)
88          data[i] = r.nextInt(100);
89       return data;
90    }
91    public static void main(String[] args){
92       SortingApp app = new SortingApp(new BubbleSort());
93       app.printArray(app.sort(getDummyData()));
94       app.changeStrategy(new SelectionSort());
95       app.printArray(app.sort(getDummyData()));
96       app.changeStrategy(new ShellSort());
97       app.printArray(app.sort(getDummyData()));
98    }
99 }

 

輸出

 1 --- BUBBLE SORT strategy in action---
 2  
 3 5 15 22 38 41 45 56 72 72 97
 4  
 5 --- SELECTION SORT strategy in action ---
 6  
 7 42 47 52 55 60 76 79 82 86 96
 8  
 9 --- SHELL SORT strategy in action ---
10  
11 11 13 19 24 27 33 47 72 72 88

 

結論

策略模式使我們能夠將有關要使用的實施策略的決策推遲到執行時為止。當我們使用Spring Framework將XML用作配置檔案來構造物件及其依賴項時,將在執行時讀取它。這種模式的主要優點是它利用了實現之間的動態變化,而無需重新編譯。

感謝閱讀!歡迎留言。想更深入探討學習也歡迎私信我。下篇繼