前言
上面這張圖是京東商城的會員體系,總共包含五種不同等級的會員,分別是注冊會員,銅牌會員,銀牌會員,黃金會員,鑽石會員。從上圖可以看出,不同等級會員享有不同的優惠服務,那么這么多優惠服務在程序中是怎么實現的呢?最直接了當的方式,就是寫一堆if else去做判斷,這顯然不是最佳實現方式,很不利於后期維護。實際上這里需要用到設計模式中的策略模式,針對不同等級的會員,每一種會員特權都拒用不同的優惠策略。
策略模式
定義算法簇,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。
策略模式結構原型
策略模式的組成
應用場景(Context):
1、需要使用ConcreteStrategy提供的算法。
2、 內部維護一個Strategy的實例。
3、 負責動態設置運行時Strategy具體的實現算法。
4、負責跟Strategy之間的交互和數據傳遞。
抽象策略(StrategyInterface): 定義了一個公共接口,各種不同的算法以不同的方式實現這個接口,Context使用這個接口調用不同的算法,一般使用接口或抽象類實現。
具體策略(Strategy):包裝了相關的算法和行為。
具體應用場景
具體策略划分
我們現在來模仿京東會員機制,將會員分為三種等級:普通會員,金牌會員,鑽石會員。以下為會員優惠服務,不同等級的會員擁有不同的優惠策略:
優惠服務\會員等級 | 普通會員 | 黃金會員 | 鑽石會員 |
會員特價 | 正常價 | 打九折 | 打九折 |
運費 | 5元 | 5元 | 包郵 |
會員策略模型
代碼實現
抽象策略角色
會員接口:MemberInterface.java
package strategy.member; /** * 會員接口 * @author vision */ public interface MemberInterface { /** * 會員價格 * @param price * @return */ public Double getPrice(Double price); /** * 是否包郵 * @return */ public boolean freeShipping(); }
具體策略角色
普通會員:NormalMember.java
package strategy.member.impl; import strategy.member.MemberInterface; /** * 普通會員 * @author vision */ public class NormalMember implements MemberInterface{ /** * 會員價格,正常價 */ public Double getPrice(Double price) { //普通會員原價銷售 return price; } /** * 不包郵 */ public boolean freeShipping() { //普通會員不包郵 return false; } }
黃金會員:GoldMember.java
package strategy.member.impl; import strategy.member.MemberInterface; /** * 黃金會員 * @author vision */ public class GoldMember implements MemberInterface{ /** * 會員價格,打九折 */ public Double getPrice(Double price) { return price*0.9; } /** * 不包郵 */ public boolean freeShipping() { return false; } }
鑽石會員:DiamondMember.java
package strategy.member.impl; import strategy.member.MemberInterface; /** * 鑽石會員 * @author vision */ public class DiamondMember implements MemberInterface{ /** * 會員價格,打九折 */ public Double getPrice(Double price) { return price*0.9; } /** * 包郵 */ public boolean freeShipping() { return true; } }
環境角色
PriceHandle.java
package strategy; import strategy.member.MemberInterface; import strategy.member.impl.DiamondMember; import strategy.member.impl.GoldMember; import strategy.member.impl.NormalMember; /** * 價格處理類 * @author vision * @date 2016年10月12日 */ public class PriceHandle { private MemberInterface memberInterface; public void setMemberInterface(MemberInterface memberInterface) { this.memberInterface = memberInterface; } /** * 計算出需要支付的費用 * @return */ private Double getMemberPrice(Double price){ Double postage=5.0; if(memberInterface.freeShipping()){ postage=0.0; } return (memberInterface.getPrice(price)+postage); } }
客戶端調用
public class TestClass{ public static void main(String[] args) { PriceHandle priceHandle=new PriceHandle(); //會員等級(0普通會員,1黃金會員,2鑽石會員) int memberType=2; switch (memberType) { case 0: priceHandle.setMemberInterface(new NormalMember()); break; case 1: priceHandle.setMemberInterface(new GoldMember()); break; case 2: priceHandle.setMemberInterface(new DiamondMember()); break; } System.out.println(priceHandle.getMemberPrice(10.0));; } }
備注
參考資料:《Head First 設計模式》