Java兩種設計模式_23種設計模式(11)java策略模式

23種設計模式第四篇:java策略模式

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

類型:行為類模式

類圖:

c2c452b595af4e50bd31df77fdd1f2bc.png

策略模式是對算法的封裝,把一系列的算法分別封裝到對應的類中,并且這些類實現相同的接口,相互之間可以替換。在前面說過的行為類模式中,有一種模式也是關注對算法的封裝——模版方法模式。

對照類圖可以看到,策略模式與模版方法模式的區別僅僅是多了一個單獨的封裝類Context,它與模版方法模式的區別在于:在模版方法模式中,調用算法的主體在抽象的父類中,而在策略模式中,調用算法的主體則是封裝到了封裝類Context中,抽象策略Strategy一般是一個接口,目的只是為了定義規范,里面一般不包含邏輯。

其實,這只是通用實現,而在實際編程中,因為各個具體策略實現類之間難免存在一些相同的邏輯,為了避免重復的代碼,我們常常使用抽象類來擔任Strategy的角色,在里面封裝公共的代碼,因此,在很多應用的場景中,在策略模式中一般會看到模版方法模式的影子。

策略模式的結構

封裝類:也叫上下文,對策略進行二次封裝,目的是避免高層模塊對策略的直接調用。

抽象策略:通常情況下為一個接口,當各個實現類中存在著重復的邏輯時,則使用抽象類來封裝這部分公共的代碼,此時,策略模式看上去更像是模版方法模式。

具體策略:具體策略角色通常由一組封裝了算法的類來擔任,這些類之間可以根據需要自由替換。

策略模式代碼實現

interface IStrategy {

public void doSomething();

}

class ConcreteStrategy1 implements IStrategy {

public void doSomething() {

System.out.println("具體策略1");

}

}

class ConcreteStrategy2 implements IStrategy {

public void doSomething() {

System.out.println("具體策略2");

}

}

class Context {

private IStrategy strategy;

public Context(IStrategy strategy){

this.strategy = strategy;

}

public void execute(){

strategy.doSomething();

}

}

public class Client {

public static void main(String[] args){

Context context;

System.out.println("-----執行策略1-----");

context = new Context(new ConcreteStrategy1());

context.execute();

System.out.println("-----執行策略2-----");

context = new Context(new ConcreteStrategy2());

context.execute();

}

}

策略模式的優缺點

策略模式的主要優點有:

策略類之間可以自由切換,由于策略類實現自同一個抽象,所以他們之間可以自由切換。

易于擴展,增加一個新的策略對策略模式來說非常容易,基本上可以在不改變原有代碼的基礎上進行擴展。

避免使用多重條件,如果不使用策略模式,對于所有的算法,必須使用條件語句進行連接,通過條件判斷來決定使用哪一種算法,在上一篇文章中我們已經提到,使用多重條件判斷是非常不容易維護的。

策略模式的缺點主要有兩個:

維護各個策略類會給開發帶來額外開銷,可能大家在這方面都有經驗:一般來說,策略類的數量超過5個,就比較令人頭疼了。

必須對客戶端(調用者)暴露所有的策略類,因為使用哪種策略是由客戶端來決定的,因此,客戶端應該知道有什么策略,并且了解各種策略之間的區別,否則,后果很嚴重。例如,有一個排序算法的策略模式,提供了快速排序、冒泡排序、選擇排序這三種算法,客戶端在使用這些算法之前,是不是先要明白這三種算法的適用情況?再比如,客戶端要使用一個容器,有鏈表實現的,也有數組實現的,客戶端是不是也要明白鏈表和數組有什么區別?就這一點來說是有悖于迪米特法則的。

適用場景

做面向對象設計的,對策略模式一定很熟悉,因為它實質上就是面向對象中的繼承和多態,在看完策略模式的通用代碼后,我想,即使之前從來沒有聽說過策略模式,在開發過程中也一定使用過它吧?至少在在以下兩種情況下,大家可以考慮使用策略模式:

幾個類的主要邏輯相同,只在部分邏輯的算法和行為上稍有區別的情況。

有幾種相似的行為,或者說算法,客戶端需要動態地決定使用哪一種,那么可以使用策略模式,將這些算法封裝起來供客戶端調用。

策略模式是一種簡單常用的模式,我們在進行開發的時候,會經常有意無意地使用它,一般來說,策略模式不會單獨使用,跟模版方法模式、工廠模式等混合使用的情況比較多。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372707.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372707.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372707.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Problem E: 平面上的點——Point類 (II)

Description 在數學上,平面直角坐標系上的點用X軸和Y軸上的兩個坐標值唯一確定。現在我們封裝一個“Point類”來實現平面上的點的操作。 根據“append.cc”,完成Point類的構造方法和show()方法,輸出各Point對象的構造和析構次序。 接口描述&a…

MFC 控件RadioButton和CheckBox區別

1. 單個RadioButton在選中后,通過點擊無法變為未選中 單個CheckBox在選中后,通過點擊可以變為未選中 2. 一組RadioButton,只能同時選中一個 一組CheckBox,能同時選中多個 3. RadioButton在大部分UI框架中默認都以圓形表示 CheckBo…

什么是ActiveMQ?

盡管Active MQ網站已經對ActiveMQ進行了詳盡的介紹,但我想在其定義中添加更多上下文。 從ActiveMQ項目的網站上: “ ActiveMQ是JMS 1.1的開源實現,是J2EE 1.4規范的一部分。” 這是我的看法:ActiveMQ是一種開源消息傳遞軟件&…

字符串倒著輸出java_Java 輸出反轉字符串

Java 輸出反轉字符串public class Test {public static void main(String args[]){try{// 獲取鍵盤輸入的字符串BufferReader f new BufferReader(new inputStreamReader(System.in));String str f.readline();for (int i str.length() -1 ; i >0 ; i--) {System.out.p…

webpack基礎入門

我相信,有不少的朋友對webpack都有或多或少的了解。網上也有了各種各樣的文章,文章內作者也寫出了不少自己對于webpack這個工具的理解。在我剛剛接觸webpack的時候,老實說,網上大部分的文章我是看不懂的。。webpack里面有很多名詞…

位運算基礎

異或運算的基礎有點忘記了 先介紹一下。。2個數異或 就是對于每一個二進制位進行位運算 具有2個特殊的性質 1、一個數異或本身恒等于0,如5^5恒等于0; 2、一個數異或0恒等于本身,如5^0恒等于5。 3 滿足交換律 1.交換數字這個性質能利用與交換數…

JAXB自定義綁定– Java.util.Date / Spring 3序列化

JaxB可以處理Java.util.Date序列化,但是需要以下格式: “ yyyy-MM-ddTHH:mm:ss ”。 如果需要將日期對象格式化為另一種格式怎么辦? 我有同樣的問題時,我正在同春MVC 3和Jackson JSON處理器 ,最…

雙足機器人簡單步態生成

讓機器人行走最簡單的方法是先得到一組步態曲線,即腿部每個關節隨時間運動的角度值。可以在ADAMS或3D Max、Blender等軟件中建立好機構/骨骼模型,設計出腳踝和髖關節的運動曲線,然后進行逆運動學解算,測量每個關節在運動過程中的轉…

重新訪問了訪客模式

訪客模式是面向對象設計中最被高估但又被低估的模式之一。 高估了它,因為它常常被選擇得太快( 可能是由建筑宇航員選擇的 ),然后以錯誤的方式添加時會膨脹本來非常簡單的設計。 如果您不遵循教科書示例,那么它可能會非…

java web開發技術大_2021年六大javaweb開發主流技術

作為歷史最為悠久的編程語言——java,歷經數十年依然盤踞在編程榜最前面的位置,這與它的技術和應用范圍是分不開的,同時呢,javaweb開發主流技術更是java開發者時時刻刻關注的問題,接下來我們一起分析一下2020年互聯網行…

ASP.NET—013:實現帶控件的彈出層(彈出框)

http://blog.csdn.net/yysyangyangyangshan/article/details/38458169 在頁面中用到彈出新頁面的情況比較多的,一般來說都是使用JS方法showModalDialog("新頁面相對路徑?參數1&參數2",window,"新頁面樣式");然后會新彈出一個模態的page頁。…

運維人員日常工作(轉自老男孩)

1)運維人員要謹記的6個字: 運維人員做事需遵循:簡單、易用、高效 (2)運維人員服務的3大宗旨: 1、企業數據安全保障。 2、7*24小時業務持續提供服務。 3、不斷提升用戶感受、體驗。 (3&#xff0…

c# 操作DatatTable

dtTemp.Columns.Add("列名");//增加一列 dtTemp.Columns.Remove("列名");//刪除一列 dtTemp.Columns["舊列名"].ColumnName "新列名";//修改列名 dtTemp.Columns["列名1"].SetOrdinal(dtTemp.Columns["列名2"].O…

java 二進制 歸屬權限_【Java EE 學習 75 上】【數據采集系統第七天】【二進制運算實現權限管理】【權限分析和設計】...

一、權限計算相關分析1.如何存儲權限首先說一下權限保存的問題,一個系統中最多有多少權限呢?一個大的系統中可能有成百上千個權限需要管理。怎么保存這么多的權限?首先,我們使用一個數字中的一位保存一種權限,那么如果…

MongoDB性能測試

因此,今天早上,我在mongo shell中四處亂逛。 我想出了三種不同的方式來聚合所需的數據,但不確定隨后應移植哪種代碼以在應用程序中使用。 那么,我將如何決定實施哪種方法呢? 好吧,讓我們選擇性能最佳的產品…

$_SERVER[SCRIPT_NAME]、$_SERVER[PHP_SELF]、$_SERVER[QUERY_STRING]、$_SERVER[REQUEST_URI]

1、$_SERVER["SCRIPT_NAME"] 說明:包含當前腳本的路徑 2、$_SERVER["PHP_SELF"] 說明:當前正在執行腳本的文件名 3、$_SERVER["QUERY_STRING"] 說明:查詢(query)的字符串 4、$_SERVER["REQUEST_URI"…

yii2增刪改查及AR的理解

yii2增刪改查 // 返回 id 為 1 的客戶 $customer Customer::findOne(1); // 返回 id 為 1 且狀態為 *active* 的客戶 $customer Customer::findOne([ id > 1, status > Customer::STATUS_ACTIVE, ]); // 返回id為1、2、3的一組客戶 $customers Customer::findAll([1, …

GWT和HTML5 Canvas演示

這是我對GWT和HTML5 Canvas的第一個實驗。 我的第一個嘗試是創建矩形,僅用幾行代碼就得出了這樣的內容: 碼: public class GwtHtml5 implements EntryPoint {static final String canvasHolderId "canvasholder";static final St…

mysql 平均值 排序_MySQL按平均兩個平均值排序

我正在競賽網站上工作,有兩種類型的用戶,普通網站成員和評委.每個人都可以使用拖放工具按照他們選擇的順序對特定比賽中的條目進行排序.完成后,相關的條目ID將附加一個排名值,然后可用于確定比賽中哪個條目獲得最高的平均分數.獲勝者實際上將通過平均每組的平均值來確定.我希望…

Solr管理界面詳解

轉載于:https://www.cnblogs.com/gslblog/p/6553813.html