將行爲抽象爲接口,在父類中持有該接口,並由該接口代替接口飛行行爲html
優勢:java
缺點:git
/** * 促銷策略類 */ public interface IPromotionStrategy { /** * 計算邏輯 */ BigDecimal promotionAlgorithm(); /** * 存入價錢 * @param price */ void setPrice(BigDecimal price); }
/** * 原價 */ public class CashNormal implements IPromotionStrategy{ private BigDecimal price; @Override public BigDecimal promotionAlgorithm() { //原價返回 return this.price; } public void setPrice(BigDecimal price) { this.price = price; } } /** * 打折 */ public class CashRebate implements IPromotionStrategy { private BigDecimal price = BigDecimal.ZERO; private BigDecimal rate; public CashRebate(BigDecimal rate) { this.rate = rate; } @Override public BigDecimal promotionAlgorithm() { //TODO 打折邏輯實現 } public void setPrice(BigDecimal price) { this.price = price; } } /** * 滿減 */ public class CashReturn implements IPromotionStrategy { private BigDecimal price; private BigDecimal minPrice; private BigDecimal subPrice; public CashReturn(BigDecimal minPrice, BigDecimal subPrice) { this.minPrice = minPrice; this.subPrice = subPrice; } @Override public BigDecimal promotionAlgorithm() { //TODO 滿減邏輯實現 } public void setPrice(BigDecimal price) { this.price = price; } }
public class PromotionContext { /** * 策略實現類包 */ private static final String PACKAGE_NAME = "org.ko.strategy.promotion"; /** * 組合策略類 */ private IPromotionStrategy promotionStrategy; /** * 獲取促銷後價錢 * @return */ public BigDecimal getPrice () { return this.promotionStrategy.promotionAlgorithm(); } /** * 建立促銷手段 * 這裏使用反射維護實例對象, 相關知識這裏再也不介紹. * @param code 對應促銷模式編碼 * @param args 對應促銷參數 */ public void newPromotion (Integer code, Object... args) { //根據促銷模式編碼獲取促銷模式對應類名稱 String clazz = PromotionType.findClazz(code); try { //經過反射獲取促銷模式的對象 this.promotionStrategy = (IPromotionStrategy)Class.forName(PACKAGE_NAME + "." + clazz) .getDeclaredConstructor(getClasses(args)).newInstance(args); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 設置打折前的價格 * @param price */ public void setPrice (BigDecimal price) { this.promotionStrategy.setPrice(price); } /** * 獲取Class * @param args * @return */ private Class[] getClasses (Object... args) { Class[] classes = new Class[args.length]; for (int i = 0; i < args.length; i ++) { classes[i] = args[i].getClass(); } return classes; } }
/** * 促銷手段樣例 */ public enum PromotionType { CashNormal(1, "CashNormal", "原價"), CashRebate(2, "CashRebate", "打折"), CashReturn(3, "CashReturn", "滿減"); private Integer code; private String clazz; private String description; PromotionType(Integer code, String clazz, String description) { this.code = code; this.clazz = clazz; this.description = description; } /** * 經過編碼獲取促銷手段 * @param code 促銷手段編碼 * @return */ public static String findClazz(Integer code) { for (PromotionType type : PromotionType.values()) { if (Objects.equals(code, type.code)) { return type.clazz; } } return null; } }
public static void main(String[] args) { //初始化上下文 PromotionContext context = new PromotionContext(); //測試無促銷 context.newPromotion(1); context.setPrice(new BigDecimal("200")); BigDecimal price = context.getPrice(); System.out.println(price); //測試打折 context.newPromotion(2, new BigDecimal("0.8")); context.setPrice(new BigDecimal("200")); price = context.getPrice(); System.out.println(price); //測試滿減 context.newPromotion(3, new BigDecimal("300"), new BigDecimal("100")); context.setPrice(new BigDecimal("200")); price = context.getPrice(); System.out.println(price); context.setPrice(new BigDecimal("300")); price = context.getPrice(); System.out.println(price); }
慕課網設計模式精講
: https://coding.imooc.com/class/270.html