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

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

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

1.IC卡类和交易信息类

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

2.扣款策略类

扣款策略有以下两种:

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

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

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


类图实现:

设计模式(java) ------ 工厂模式+策略模式+门面模式_第1张图片

主要涉及如下几个角色:

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,设计模式,工厂模式)