Java經(jīng)典設(shè)計(jì)模式之策略模式原理與用法詳解
本文實(shí)例講述了Java經(jīng)典設(shè)計(jì)模式之策略模式。分享給大家供大家參考,具體如下:
策略模式指:策略模式指將程序中可變部分抽象分離成一系列的算法,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。
策略模式一般由下面三部分組成:
1. 抽象策略角色: 策略類,通常由一個(gè)接口或者抽象類實(shí)現(xiàn)。
2. 具體策略角色:包裝了相關(guān)的算法和行為。
3. 環(huán)境角色:持有某一個(gè)策略類的引用,客戶端調(diào)用。
策略模式設(shè)計(jì)原則:
1. 把程序中需要變化的部分抽離出來,獨(dú)立于不變的部分
2. 面向接口編程,而不是面向?qū)崿F(xiàn)編程,多作組合 ,少用繼承。(組合 :在類中增加一個(gè)私有域,引用另外一個(gè)已經(jīng)有的類的實(shí)例,通過調(diào)用實(shí)例的方法從而獲得新的功能)
應(yīng)用舉例,以銀行為例,可能有點(diǎn)不恰當(dāng)
比如我們應(yīng)用要接入銀行支付功能。我們都知道,銀行都有支付功能,隨著技術(shù)的發(fā)展,銀行具有了開通網(wǎng)絡(luò)支付的功能。現(xiàn)在我們遇到的問題是,我們要增加支付的銀行,但是有的銀行還沒有開通網(wǎng)絡(luò)銀行,有的已經(jīng)開通了,而且也要把原有接入 的銀行添加上網(wǎng)絡(luò)銀行功能(如果已經(jīng)開通的話)。
//銀行基類,為了適應(yīng)變化,增加了網(wǎng)絡(luò)支付處理的策略處理接口BankStrategy
public abstract class Bank {
private BankStrategy mBankStrategy;
public void setmStrategy(BankStrategy mStrategy) {
this.mBankStrategy = mStrategy;
}
public void payMoney() {
System.out.println("我具有支付功能");// 所有銀行共同的特征
}
public abstract void serviceStyle();// 但每個(gè)銀行有不同的服務(wù)方法(比的就是服務(wù)),具體的子類實(shí)現(xiàn)
public void netBank(){//開通網(wǎng)上銀行
mBankStrategy.netPay();
}
}
//———-銀行策略接口———————————
public interface BankStrategy {
void netPay();// 添加網(wǎng)絡(luò)支付功能
}
//————–增加開通網(wǎng)絡(luò)支付的策略實(shí)現(xiàn)類————
public class CanNetBank implements BankStrategy {
@Override
public void netPay() {
System.out.println("我已經(jīng)開通網(wǎng)絡(luò)支付功能");
}
}
//————–也有不開通網(wǎng)絡(luò)支付的銀行—————
public class NoNetBank implements BankStrategy {
@Override
public void netPay() {
System.out.println("我不開通網(wǎng)絡(luò)銀行,咋的!");
}
}
//——-地球銀行:現(xiàn)在開通網(wǎng)絡(luò)支付——————
public class EarthBank extends Bank {
public EarthBank(){
super();
super.setmStrategy(new CanNetBank());//這里就實(shí)現(xiàn)了網(wǎng)絡(luò)支付
}
@Override
public void serviceStyle() {
System.out.println("我的服務(wù)在事個(gè)地球上是最好的!");
}
}
//——–太陽銀行,說離我們太遠(yuǎn)了,不開通網(wǎng)絡(luò)銀行——————-
public class SunBank extends Bank {
public SunBank(){
super();
super.setmStrategy(new NoNetBank());//這里就不開通了(當(dāng)然可不調(diào)用 ,只是告訴下實(shí)現(xiàn)方法)
}
@Override
public void serviceStyle() {
System.out.println("我的服務(wù)像金子一樣發(fā)光!");
}
}
//———測試類———————————–
public class Test {
public static void main(String[] args) {
System.out.println("———測試———–");
Bank duck=null;
duck=new EarthBank();
duck.serviceStyle();
duck.payMoney();
duck.netBank();
System.out.println("———測試———–");
duck=new SunBank();
duck.serviceStyle();
duck.payMoney();
duck.netBank();
}
}
結(jié)果打印

策略模式的優(yōu)點(diǎn):
1、 提供了管理相關(guān)的算法策略類,恰當(dāng)使用繼承可以把公共的代碼轉(zhuǎn)移到父類里面,避免重復(fù)的代碼,使得架構(gòu)也更加靈活。
2、 提供了可以替換繼承關(guān)系的辦法(組合)。繼承也可以處理多種算法或行為,但算法或行為的環(huán)境類就可能會(huì)有一些子類,每一個(gè)子類提供一個(gè)不同的算法或行為。這樣一來算法或行為的使用者就和算法或行為本身混在一起。使得動(dòng)態(tài)改變算法變得復(fù)雜甚至不可行,也不符合開閉原則。
3、 相對于繼承代碼更好地得到復(fù)用,同時(shí)可以避免使用多重條件轉(zhuǎn)移語句。
策略模式的缺點(diǎn):
1、客戶代碼需要了解個(gè)策略實(shí)現(xiàn)的細(xì)節(jié),只適用于客戶端知道所有的算法或行為的情況。
2、 策略模式造成很多的策略類,每個(gè)具體策略類都會(huì)產(chǎn)生一個(gè)新類,增加了對象的數(shù)目。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計(jì)有所幫助。
- Java設(shè)計(jì)模式之策略模式原理與用法實(shí)例詳解
- Java設(shè)計(jì)模式之策略模式定義與用法詳解
- 23種設(shè)計(jì)模式(11)java策略模式
- java設(shè)計(jì)模式學(xué)習(xí)之策略模式
- Java設(shè)計(jì)模式之策略模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java設(shè)計(jì)模式之策略模式詳解
- 對比Java設(shè)計(jì)模式編程中的狀態(tài)模式和策略模式
- 詳解Java設(shè)計(jì)模式編程中的策略模式
- Java設(shè)計(jì)模式之策略模式(Strategy模式)介紹
- Java通俗易懂系列設(shè)計(jì)模式之策略模式
相關(guān)文章
Java實(shí)現(xiàn)將PPT轉(zhuǎn)為OFD過程詳解
本文將通過Java后端程序代碼展示如何實(shí)現(xiàn)將PPT幻燈片轉(zhuǎn)成OFD格式,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下2022-01-01
Java實(shí)現(xiàn)word/pdf轉(zhuǎn)html并在線預(yù)覽
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)word、pdf文件轉(zhuǎn)html并在線預(yù)覽的功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-05-05
Java趣味練習(xí)題之輸出兩個(gè)日期之間的相隔天數(shù)
本篇文章介紹了我看到的一個(gè)趣味小題目,怎么求得兩個(gè)日期之間相隔的天數(shù),以及解決該題目的過程及思路,通讀本篇對大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下2021-10-10
springboot項(xiàng)目mysql-connector-java默認(rèn)版本如何查看
這篇文章主要介紹了springboot項(xiàng)目mysql-connector-java默認(rèn)版本如何查看問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Java使用XML與注解方式實(shí)現(xiàn)CRUD操作代碼
MyBatis提供了靈活的配置和使用方式,使得數(shù)據(jù)庫操作更加簡潔和高效,通過本文,我們介紹了如何使用MyBatis框架,通過XML映射文件和注解兩種方式來實(shí)現(xiàn)數(shù)據(jù)庫的增刪改查操作,感興趣的朋友跟隨小編一起看看吧2024-02-02
在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡單實(shí)例
這篇文章介紹了在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡單實(shí)例,有需要的朋友可以參考一下2013-09-09
教你使用Java實(shí)現(xiàn)掃雷小游戲(最新完整版)
本文給大家介紹使用Java實(shí)現(xiàn)掃雷小游戲,本程序封裝了五個(gè)類,分別是主類GameWin類,繪制底層地圖和繪制頂層地圖的類MapBottom類和MapTop類,繪制底層數(shù)字的類BottomNum類,以及初始化地雷的BottomRay類和工具GameUtil類,用于存靜態(tài)參數(shù)和方法,感興趣的朋友一起看看吧2022-05-05

