標籤:設計 使用者 相互 valueof 示範 時間 private 功能 crete
策略模式
策略模式的定義是:定義了一系列的演算法,把它們一個個的封裝起來,並且使它們可相互替換,讓演算法可以獨立於使用它的客戶而變化。
設計原則是:把一個類中經常改變或者將來可能會經常改變的部分提取出來作為一個介面,然後在使用類中包含這個介面的執行個體,這樣使用類的對象就可以隨意調用實現了這個介面的類行為。
在策略模式中有如下幾個角色:
環境角色(Context): 此角色中實現了對策略角色的引用和使用。
抽象策略角色:此角色通常由抽象類別或介面來實現,定義了,所以具體策略角色的行為。
具體策略角色:此角色封裝了實現不同功能的不同演算法。
示範代碼如下:
抽象策略類
public interface Strategy { /** * 策略方法 */ void strategyMethod();}
具體角色類A
public class ConcreteStrategyA implements Strategy{ @Override public void strategyMethod() { //具體的行為 }}
具體角色類B
public class ConcreteStrategyB implements Strategy { @Override public void strategyMethod() { //具體的行為 }}
環境角色類
public class Context { /** * 持有一個具體的策略對象 */ private Strategy strategy; /** * 構造方法,傳入一個具體的策略對象 * @param strategy 具體的策略對象 */ public Context(Strategy strategy) { this.strategy = strategy; } /** * 對外提供的使用原則的方法 */ public void contextMethod() { //通常會轉調具體的策略對象進行演算法運算 strategy.strategyMethod(); }}策略模式具體情境例子
某Saas公司的企業服務系統,在銷售時,會根據客戶的購買時間長度來確定優惠策略,分為普通客戶(無優惠政策),大客戶(98折),戰略客戶(95折)。普通客戶是指一次性租用服務在一到3年之間的,大客戶指一次性使用服務3到5年之間的,戰略客戶指一次性使用服務5年以上的。因為每種客戶價格演算法不同,所以這個情境就可以使用原則模式。
定義一個計算價格行為的介面
public interface SalePrice { /** * 根據原價返回不同的價格 * @param originalPrice 原始價格 * @return */ BigDecimal salePrice(BigDecimal originalPrice);}
然後定義三中客戶的具體計算價格類(策略類)
public class OriginalCustomer implements SalePrice { /** * 普通客戶直接返回原價 * @param originalPrice 原始價格 * @return 計算後的價格 */ @Override public BigDecimal salePrice(BigDecimal originalPrice) { return originalPrice.multiply(BigDecimal.valueOf(1)); }}
public class LargeCustomer implements SalePrice { /** * 大客戶返回98折價格 * @param originalPrice 原始價格 * @return 計算後的價格 */ @Override public BigDecimal salePrice(BigDecimal originalPrice) { return originalPrice.multiply(BigDecimal.valueOf(0.98)); }}
public class StrategicCustomer implements SalePrice { /** * 戰略客戶直接返回95折價格 * @param originalPrice 原始價格 * @return 計算後的價格 */ @Override public BigDecimal salePrice(BigDecimal originalPrice) { return originalPrice.multiply(BigDecimal.valueOf(0.95)); }}
客戶類,需要判斷具體的調用哪個計算價格的方法
public class Customer { private int years; /** 租用服務一年的初始價格 */ private BigDecimal originalPrice = BigDecimal.valueOf(50000); /** 客戶最終支付的價格 **/ private BigDecimal payForPrice = BigDecimal.ZERO; /** 每個客戶的初始價格都是原價 */ private SalePrice salePrice = new OriginalCustomer(); /** * 根據客戶購買的時間長度來計算每一年的優惠價格(單位:年) * @param years */ public void buy(int years) { this.years = years; payForPrice = originalPrice.multiply(BigDecimal.valueOf(years)); //大於5年的戰略客戶價格 if(years >= 5){ salePrice = new StrategicCustomer(); }else if(years >= 3)//3年到5年的大客戶優惠價格 { salePrice = new LargeCustomer(); }else if(years >= 1)//1到3年的普通使用者原價 { salePrice = new OriginalCustomer(); } } /** * 計算客戶最終支付的價格 * @return */ public BigDecimal payPrice(){ return salePrice.salePrice(payForPrice); }}
用戶端調用類,自動計算支付價格
** * 用戶端調用類 */@Slf4jpublic class Client { public static void main(String[] args){ Customer customer = new Customer(); customer.buy(1); log.info("客戶需支付:{}",customer.payPrice()); customer.buy(3); log.info("客戶需支付:{}",customer.payPrice()); customer.buy(6); log.info("客戶需支付:{}",customer.payPrice()); }}
輸出結果:
客戶需支付:50000客戶需支付:147000.00客戶需支付:285000.00
根據輸出結果可以看出購買不同時間的服務,收費價格是不同的。這樣客戶可以不用依賴具體的收費方法,直接根據需要的服務的時間購買即可。
java設計模式之策略模式