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

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

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

1.IC卡类和交易信息类

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

2.扣款策略类

扣款策略有以下两种:

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

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

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


类图实现:

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

主要涉及如下几个角色:

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)模式:负责对复杂的扣款系统进行封转,封转的结果就是避免高层模块深入子系统内部,同时提供系统高内聚、低耦合的特性。

 

你可能感兴趣的:(java)