深入了解Java行為型設(shè)計(jì)模式之策略模式
策略模式
策略模式(Strategy Pattern)也叫政策模式(Policy Pattern),屬于行為型模式。
它是將定義的一系列算法、分別封裝起來,讓它們之間可以互相替換,從而讓算法的變化不會(huì)影響到使用算法的用戶。
策略模式能讓你定義一系列算法, 并將每種算法分別放入獨(dú)立的類中, 以使算法的對(duì)象能夠相互替換。
應(yīng)用場(chǎng)景
1、針對(duì)同一類型問題,有多種處理方式,每一種都能獨(dú)立解決問題。
2、算法需要自由切換的場(chǎng)景。
3、需要屏蔽算法規(guī)則的場(chǎng)景。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1.可以在運(yùn)行時(shí)切換對(duì)象內(nèi)的算法。
2.避免使用多重條件轉(zhuǎn)移語句,如if.else.語句、switch語句
3.使用策略模式可以提高算法的保密性和安全性。
4.可以將算法的實(shí)現(xiàn)和使用算法的代碼隔離開來。
缺點(diǎn):
1.客戶端必須知道所有的策略,所有策略類都需要對(duì)外暴露,并且自行決定使用哪一個(gè)策略類。
2.代碼中會(huì)產(chǎn)生非常多策略類,增加維護(hù)難度。
主要角色
1.抽象策略角色(Strategy)
規(guī)定策略或算法的行為。
2.具體策略角色(ConcreteStrategy)
具體的策略或算法實(shí)現(xiàn)。
3.上下文角色(Context)
用來操作策略的上下文環(huán)境,屏蔽高層模塊(客戶瑞)對(duì)策略,算法的直接訪問,封裝可能存在的變化。
策略模式的基本使用
創(chuàng)建抽象策略角色
public interface IStrategy { /** * 算法、策略 */ void algorithm(); }
創(chuàng)建具體策略角色
public class ConcreteStrategyA implements IStrategy { public void algorithm() { System.out.println("Strategy A 打9折"); } }
public class ConcreteStrategyB implements IStrategy { public void algorithm() { System.out.println("Strategy B 打8折"); } }
創(chuàng)建上下文角色
public class Context { private IStrategy mStrategy; public Context(IStrategy strategy) { this.mStrategy = strategy; } public void algorithm() { this.mStrategy.algorithm(); } }
客戶端執(zhí)行
public static void main(String[] args) { // 創(chuàng)建具體策略 IStrategy strategyA = new ConcreteStrategyA(); IStrategy strategyB = new ConcreteStrategyB(); // 創(chuàng)建上下文環(huán)境 Context contextA = new Context(strategyA); Context contextB = new Context(strategyB); //客戶端直接讓上下文環(huán)境執(zhí)行算法 contextA.algorithm(); contextB.algorithm(); }
Strategy A 打9折
Strategy B 打8折
策略模式實(shí)現(xiàn)支付方式的選擇
創(chuàng)建抽象策略角色
創(chuàng)建支付抽象類,定義支付邏輯
public abstract class Payment { /** * 支付類型 */ public abstract String getName(); /** * 支付 * @param uid 用戶id * @param amount 金額 * @return 支付結(jié)果 */ public String pay(String uid, double amount){ if(queryBalance(uid) < amount){ return "支付失敗,"+"商品金額:"+amount+" ,用戶余額:"+queryBalance(uid); } return "支付成功,"+"商品金額:"+amount+" ,用戶余額:"+(queryBalance(uid)-amount); } /** * 余額查詢 * @param uid 用戶id * @return 余額 */ protected abstract double queryBalance(String uid); }
創(chuàng)建具體策略角色
創(chuàng)建具體支付方式,如AliPay 、WechatPay 、UnionPay等三種方式。
public class AliPay extends Payment { public String getName() { return "支付寶"; } protected double queryBalance(String uid) { return 500; } } public class WechatPay extends Payment { public String getName() { return "微信支付"; } protected double queryBalance(String uid) { return 600; } } public class UnionPay extends Payment { public String getName() { return "銀聯(lián)支付"; } protected double queryBalance(String uid) { return 800; } }
創(chuàng)建上下文角色
創(chuàng)建上下文角色,
public class PayStrategy { public static final String ALI_PAY = "AliPay"; public static final String WECHAT_PAY = "WechatPay"; public static final String UNION_PAY = "UnionPay"; public static final String DEFAULT_PAY = ALI_PAY; private static Map<String, Payment> strategy = new HashMap<String, Payment>(); static { strategy.put(ALI_PAY, new AliPay()); strategy.put(WECHAT_PAY, new WechatPay()); strategy.put(UNION_PAY, new UnionPay()); } public static Payment get(String payKey) { if (!strategy.containsKey(payKey)) { return strategy.get(DEFAULT_PAY); } return strategy.get(payKey); } }
客戶端執(zhí)行
public class Order { private String uid; private String name; private double price; public Order(String uid, String name, double price) { this.uid = uid; this.name = name; this.price = price; } public String pay() { return pay(PayStrategy.DEFAULT_PAY); } public String pay(String payKey) { Payment payment = PayStrategy.get(payKey); System.out.println("購(gòu)買:"+name+" ,使用" + payment.getName() + "支付, " + "支付金額為: " + price); return payment.pay(uid, price); } }
public static void main(String[] args) { Order order = new Order("001","皮皮蝦",500.5); System.out.println(order.pay()); System.out.println("----------------------------------------------------"); System.out.println(order.pay(PayStrategy.WECHAT_PAY)); }
購(gòu)買:皮皮蝦 ,使用支付寶支付, 支付金額為: 500.5
支付失敗,商品金額:500.5 ,用戶余額:500.0
----------------------------------------------------
購(gòu)買:皮皮蝦 ,使用微信支付支付, 支付金額為: 500.5
支付成功,商品金額:500.5 ,用戶余額:99.5
到此這篇關(guān)于深入了解Java行為型設(shè)計(jì)模式之策略模式的文章就介紹到這了,更多相關(guān)Java策略模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
支票金額大寫轉(zhuǎn)換示例(金額大寫轉(zhuǎn)換器)
這篇文章主要介紹了支票金額大寫轉(zhuǎn)換示例(金額大寫轉(zhuǎn)換器),需要的朋友可以參考下2014-02-02SpringBoot2.x 整合 thumbnailator 圖片處理的示例代碼
這篇文章主要介紹了SpringBoot2.x 之整合 thumbnailator 圖片處理,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10使用Springboot對(duì)配置文件中的敏感信息加密
這篇文章主要介紹了使用Springboot對(duì)配置文件中的敏感信息加密方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java Validation Api實(shí)現(xiàn)原理解析
這篇文章主要介紹了Java Validation Api實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09詳解mybatis批量插入10萬條數(shù)據(jù)的優(yōu)化過程
這篇文章主要介紹了詳解mybatis批量插入10萬條數(shù)據(jù)的優(yōu)化過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04java的SimpleDateFormat線程不安全的幾種解決方案
但我們知道SimpleDateFormat是線程不安全的,處理時(shí)要特別小心,要加鎖或者不能定義為static,要在方法內(nèi)new出對(duì)象,再進(jìn)行格式化,本文就介紹了幾種方法,感興趣的可以了解一下2021-08-08