Java經(jīng)典設(shè)計模式之策略模式原理與用法詳解
本文實例講述了Java經(jīng)典設(shè)計模式之策略模式。分享給大家供大家參考,具體如下:
策略模式指:策略模式指將程序中可變部分抽象分離成一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。
策略模式一般由下面三部分組成:
1. 抽象策略角色: 策略類,通常由一個接口或者抽象類實現(xiàn)。
2. 具體策略角色:包裝了相關(guān)的算法和行為。
3. 環(huán)境角色:持有某一個策略類的引用,客戶端調(diào)用。
策略模式設(shè)計原則:
1. 把程序中需要變化的部分抽離出來,獨立于不變的部分
2. 面向接口編程,而不是面向?qū)崿F(xiàn)編程,多作組合 ,少用繼承。(組合 :在類中增加一個私有域,引用另外一個已經(jīng)有的類的實例,通過調(diào)用實例的方法從而獲得新的功能)
應(yīng)用舉例,以銀行為例,可能有點不恰當(dāng)
比如我們應(yīng)用要接入銀行支付功能。我們都知道,銀行都有支付功能,隨著技術(shù)的發(fā)展,銀行具有了開通網(wǎng)絡(luò)支付的功能?,F(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();// 但每個銀行有不同的服務(wù)方法(比的就是服務(wù)),具體的子類實現(xiàn)
public void netBank(){//開通網(wǎng)上銀行
mBankStrategy.netPay();
}
}
//———-銀行策略接口———————————
public interface BankStrategy {
void netPay();// 添加網(wǎng)絡(luò)支付功能
}
//————–增加開通網(wǎng)絡(luò)支付的策略實現(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());//這里就實現(xiàn)了網(wǎng)絡(luò)支付
}
@Override
public void serviceStyle() {
System.out.println("我的服務(wù)在事個地球上是最好的!");
}
}
//——–太陽銀行,說離我們太遠(yuǎn)了,不開通網(wǎng)絡(luò)銀行——————-
public class SunBank extends Bank {
public SunBank(){
super();
super.setmStrategy(new NoNetBank());//這里就不開通了(當(dāng)然可不調(diào)用 ,只是告訴下實現(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)點:
1、 提供了管理相關(guān)的算法策略類,恰當(dāng)使用繼承可以把公共的代碼轉(zhuǎn)移到父類里面,避免重復(fù)的代碼,使得架構(gòu)也更加靈活。
2、 提供了可以替換繼承關(guān)系的辦法(組合)。繼承也可以處理多種算法或行為,但算法或行為的環(huán)境類就可能會有一些子類,每一個子類提供一個不同的算法或行為。這樣一來算法或行為的使用者就和算法或行為本身混在一起。使得動態(tài)改變算法變得復(fù)雜甚至不可行,也不符合開閉原則。
3、 相對于繼承代碼更好地得到復(fù)用,同時可以避免使用多重條件轉(zhuǎn)移語句。
策略模式的缺點:
1、客戶代碼需要了解個策略實現(xiàn)的細(xì)節(jié),只適用于客戶端知道所有的算法或行為的情況。
2、 策略模式造成很多的策略類,每個具體策略類都會產(chǎn)生一個新類,增加了對象的數(shù)目。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
Java實現(xiàn)將PPT轉(zhuǎn)為OFD過程詳解
本文將通過Java后端程序代碼展示如何實現(xiàn)將PPT幻燈片轉(zhuǎn)成OFD格式,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下2022-01-01
Java實現(xiàn)word/pdf轉(zhuǎn)html并在線預(yù)覽
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實現(xiàn)word、pdf文件轉(zhuǎn)html并在線預(yù)覽的功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-05-05
Java趣味練習(xí)題之輸出兩個日期之間的相隔天數(shù)
本篇文章介紹了我看到的一個趣味小題目,怎么求得兩個日期之間相隔的天數(shù),以及解決該題目的過程及思路,通讀本篇對大家的學(xué)習(xí)或工作具有一定的價值,需要的朋友可以參考下2021-10-10
springboot項目mysql-connector-java默認(rèn)版本如何查看
這篇文章主要介紹了springboot項目mysql-connector-java默認(rèn)版本如何查看問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
Java使用XML與注解方式實現(xiàn)CRUD操作代碼
MyBatis提供了靈活的配置和使用方式,使得數(shù)據(jù)庫操作更加簡潔和高效,通過本文,我們介紹了如何使用MyBatis框架,通過XML映射文件和注解兩種方式來實現(xiàn)數(shù)據(jù)庫的增刪改查操作,感興趣的朋友跟隨小編一起看看吧2024-02-02
在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時間的簡單實例
這篇文章介紹了在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時間的簡單實例,有需要的朋友可以參考一下2013-09-09

