设计模式(java) ------ 工厂模式+策略模式+门面模式

来源:互联网 发布:undo歌曲知乎 编辑:程序博客网 时间:2024/06/05 11:25

场景:设计一个交易系统中的子模块------扣款子模块

扣款子模块中主要包括两部分:

1.IC卡类和交易信息类

其中IC卡中包括两种金额:固定金额和自由金额;交易信息类负责记录每一笔交易。

2.扣款策略类

扣款策略有以下两种:

a. IC卡固定金额 = IC卡现有固定金额-交易金额/2

    IC卡自由金额 = IC卡自由金额-交易金额/2

b. 全部消费从IC卡自由金额中扣除


类图实现:

主要涉及如下几个角色:

1.IC卡类和交易类

2.扣款策略接口

3.扣款策略的封装类

4.策略枚举类

5.策略工厂

6.扣款模块封装

7.场景类


代码实现

Card类:

package org.apache.java.designpatter.factoryandstrategy;public class Card {private String No;private int steadyMoney;   //卡内固定交易金额private int freeMoney;  //卡内自由交易金额public String getNo() {return No;}public void setNo(String no) {No = no;}public int getSteadyMoney() {return steadyMoney;}public void setSteadyMoney(int steadyMoney) {this.steadyMoney = steadyMoney;}public int getFreeMoney() {return freeMoney;}public void setFreeMoney(int freeMoney) {this.freeMoney = freeMoney;}}

Trade类:

public class Trade {private String tradeNo;private int mount;   //交易金额public String getTradeNo() {return tradeNo;}public void setTradeNo(String tradeNo) {this.tradeNo = tradeNo;}public int getMount() {return mount;}public void setMount(int mount) {this.mount = mount;}}

扣款策略接口

public interface IDeduction {public boolean exec(Card card, Trade trade);}

扣款策略类

public class SteadyDeduction implements IDeduction {public boolean exec(Card card, Trade trade) {int halfMoney = (int) Math.rint(trade.getMount() / 2.0);card.setSteadyMoney(card.getSteadyMoney() - halfMoney);card.setFreeMoney(card.getFreeMoney() - halfMoney);return true;}}public class FreeDeduction implements IDeduction {public boolean exec(Card card, Trade trade) {card.setFreeMoney(card.getFreeMoney() - trade.getMount());return true;}}

扣款策略封装

public class DeductionContext {private IDeduction deduction;public DeductionContext(IDeduction deduction) {this.deduction = deduction;}public boolean exec(Card card, Trade trade) {return this.deduction.exec(card, trade);}}

策略枚举

public enum StrategyManage {SteadyDeduction("org.apache.java.designpatter.factoryandstrategy.SteadyDeduction"),FreeDeducation("org.apache.java.designpatter.factoryandstrategy.FreeDeduction");String value = "";private StrategyManage(String value) {this.value = value;}public String getValue() {return value;}}

策略工厂

public class StrategyFactory {public static IDeduction getDeduction(StrategyManage strategy) {IDeduction deduction = null;try {deduction = (IDeduction) Class.forName(strategy.getValue()).newInstance();} catch (Exception e) {e.printStackTrace();}return deduction;}}

扣款模块封装

public class DeductionFacade {public static Card deduct(Card card, Trade trade) {StrategyManage reg = getDeducationType(trade);    //获得消费策略IDeduction deduction = StrategyFactory.getDeduction(reg);   //初始化一个消费策略 对象DeductionContext context = new DeductionContext(deduction);    //执行封装context.exec(card, trade);    //执行扣款return card;}private static StrategyManage getDeducationType(Trade trade) {if (trade.getTradeNo().contains("abc")) {return StrategyManage.FreeDeducation;}else {return StrategyManage.SteadyDeduction;}}}

场景类

public class Client {private static Card initCard() {Card card = new Card();card.setNo("");card.setFreeMoney(0);card.setSteadyMoney(0);return card;}private static Trade initTrade() {Trade trade = new Trade();trade.setMount(0);trade.setTradeNo("");return trade;}public static void main(String[] args) {Card card = initCard();boolean flag = true;while (flag) {Trade trade = initTrade();DeductionFacade.deduct(card, trade);}}}

在该场景中用到如下几个设计模式:

策略(strategy)模式:负载对扣款策略进行封装,保证了两个策略可以自由的切换。

工厂(factory)模式:修正策略模式必须对外暴露具体策略的问题,由工厂模式直接产生一个具体策略对象,其他模块则不需要依赖具体策略。

门面(facade)模式:负责对复杂的扣款系统进行封转,封转的结果就是避免高层模块深入子系统内部,同时提供系统高内聚、低耦合的特性。