设计模式-简单工厂设计模式与策略模式之java实现二

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013871100/article/details/53705547

设计模式-简单工厂设计模式与策略模式之java实现二

     接上一篇博客,继续讲“商场促销”方案的实现。上一篇博客,我们采用简单工厂模式造各种“促销方案”的对象,然后,这也造成了一个不足之处:当促销方案多了之后,那这个工厂岂不是会越来越庞大,进而可能会走上相当臃肿的道路。于是乎,我们想改变这种策略,采用了策略模式;

     将各种算法(这里指各种促销方案)各自进行封装,抽取出其中的接口,之后开发一个CashContext,提供getResult方法,其中该方法目的用于根据参数造对象,只不过造对象的方法不同于工厂模式。下面看看这个CashContext的代码StrategyMode.java:

package com.simpleFactoryMode;

import com.strategy.IStrategyCash;
import com.strategy.StrategyCashNormal;
import com.strategy.StrategyCashRebate;
import com.strategy.StrategyCashReturn;

/**
 * 策略模式
 * @author zhonglinsen
 *
 */
public class StrategyMode {
	
	private IStrategyCash strategyCash;

	/**
	 * 获取收费实例
	 * @param mode 选取模式(收费的方式)
	 * @param money 当前本应收费
	 * @param rebate 打折策略的打折
	 * @param moneyCondition 返利策略的满额
	 * @param moneyReturn 返利策略的返额
	 * @return
	 * @throws Exception 
	 */
	public StrategyMode(String mode,String money,String rebate,String moneyCondition,String moneyReturn) throws Exception {
		
		switch (mode) {
		case "1":
			//正常收费
			strategyCash=new StrategyCashNormal();
			break;
		case "2":
			//打折
			strategyCash=new StrategyCashRebate(Double.parseDouble(rebate));
			break;
		case "3":
			//返利
			strategyCash=new StrategyCashReturn(Double.parseDouble(moneyCondition), Double.parseDouble(moneyReturn));
			break;
		default:
			break;
		}
	}
	
	/**
	 * 具体的收费方法
	 * @param money
	 * @return
	 */
	public double getResult(double money){
		return strategyCash.getResult(money);
	}
	
}

    我们设计这个类的时候,将收费的方法放在这个类中,而不是暴露在客户端了,再看看客户端的写法StrategyCodeServlet2.java:

package com.designModeServlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import com.simpleFactoryMode.StrategyMode;
import com.util.ResponseUtil;

/**
 * 策略模式
 * @author zhonglinsen
 *
 */
public class StrategyCodeServlet2 extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6165004124140768399L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		JSONObject result=new JSONObject();
		
		String mode=request.getParameter("mode");
		String money=request.getParameter("money");
		String rebate=request.getParameter("rebate");
		String moneyCondition=request.getParameter("moneyCondition");
		String moneyReturn=request.getParameter("moneyReturn");
		
		StrategyMode strategyMode=null;
		try {
			strategyMode = new StrategyMode(mode, money, rebate, moneyCondition, moneyReturn);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		double cashResult=strategyMode.getResult(Double.parseDouble(money));
		
		result.put("cashResult", cashResult);
		try {
			ResponseUtil.write(response, result);
		} catch (Exception e) {
			System.out.println("异常信息: "+e.getMessage());
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

策略模式的客户端代码,只是暴露StrategyMode这个CashContext而已:


而简单工厂模式的客户端代码,则暴露了接口IStrategyCash跟工厂类SimpleFactoryMode,


     前端页面与Js代码已经在上一篇贴出来了,就不多说了!

     紧接着,我们考虑到在造对象的方式上,还是免不了需要去判断是哪一种方案(switch...cash就是证明),而正如我所言,方案 如果多了,还是会使得switch..cash变得庞大。。。于是乎,我想到了结合反射。

     但是,可能是还没精通反射,故而,我对类跟接口进行重新设计,并在前端设计好方案的选择,通过加载一个属性配置文件读取得知客户将调用哪一个方案类strategyProperties.properties:

StrategyCashNormal=com.strategy.reflect.StrategyCashNormal
StrategyCashRebate=com.strategy.reflect.StrategyCashRebate
StrategyCashReturn=com.strategy.reflect.StrategyCashReturn

     然后,就通过这个来造对象了:

package com.simpleFactoryMode;

import java.io.FileInputStream;
import java.util.Properties;

import com.strategy.reflect.IStrategyCash;

/**
 * 策略模式 + 反射
 * @author zhonglinsen
 *
 */
public class ReflectStrategyMode {
	
	//加载属性配置文件,并进行读取特定的对象名称
	private static Properties prop=new Properties();
	
	public ReflectStrategyMode(String fileUrl) {
		try {
			prop.load(new FileInputStream(fileUrl));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ReflectStrategyMode() {
	}
	
	/**
	 * 获取结果
	 * @param mode
	 * @param money
	 * @param rebate
	 * @param moneyCondition
	 * @param moneyReturn
	 * @return
	 * @throws Exception
	 */
	public double getResult(String mode,String money,String rebate,String moneyCondition,String moneyReturn) throws Exception {
		
		IStrategyCash strategyCash= (IStrategyCash) Class.forName(String.valueOf(prop.get(mode))).newInstance();
		double finalCash=
				strategyCash.getResult(stringToDouble(money), stringToDouble(rebate), stringToDouble(moneyCondition), stringToDouble(moneyReturn));
		
		return finalCash;
	}
	
	public double stringToDouble(String param){
		return Double.parseDouble(param);
	}
	
}
而客户端类StrategyCodeServlet3.java

package com.designModeServlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import com.simpleFactoryMode.ReflectStrategyMode;
import com.util.ResponseUtil;

/**
 * 策略模式 反射
 * @author zhonglinsen
 *
 */
public class StrategyCodeServlet3 extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6165004124140768399L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		JSONObject result=new JSONObject();
		
		String mode=request.getParameter("mode");
		String money=request.getParameter("money");
		String rebate=request.getParameter("rebate");
		String moneyCondition=request.getParameter("moneyCondition");
		String moneyReturn=request.getParameter("moneyReturn");
		
		//servlet获取项目路径:得到的是一个临时路径
		///E:/java_BasicWeb/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/javaDesignMode/WEB-INF/classes/com/
		String rootPath=this.getClass().getResource("").getPath();
		int index = rootPath.lastIndexOf("/",rootPath.lastIndexOf("/")-1) + 1;
		String newPath=rootPath.substring(0,index);
		String fireUrl=newPath+"configs/strategyProperties.properties";
		//FileInputStream fileInputStream=new FileInputStream(fireUrl);
		
		double finalCash=0.0;
		try {
			ReflectStrategyMode strategyMode=new ReflectStrategyMode(fireUrl);
			finalCash=strategyMode.getResult(mode, money, rebate, moneyCondition, moneyReturn);
			System.out.println(finalCash);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		result.put("cashResult", finalCash);
		try {
			ResponseUtil.write(response, result);
		} catch (Exception e) {
			System.out.println("异常信息: "+e.getMessage());
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}
对于接口的设计:

package com.strategy.reflect;

public interface IStrategyCash {

	double getResult(double money,double rebate,double moneyCondition,double moneyReturn);
	
}
正常收费:

package com.strategy.reflect;

public class StrategyCashNormal implements IStrategyCash {

	@Override
	public double getResult(double money, double rebate, double moneyCondition,
			double moneyReturn) {
		return money;
	}

}
打折的:

package com.strategy.reflect;

public class StrategyCashRebate implements IStrategyCash {

	@Override
	public double getResult(double money, double rebate, double moneyCondition,
			double moneyReturn) {
		return money*rebate;
	}

}
满300返100

package com.strategy.reflect;

public class StrategyCashReturn implements IStrategyCash {

	@Override
	public double getResult(double money, double rebate, double moneyCondition,
			double moneyReturn) {
		double result=money;
		
		if (money>=moneyCondition) {
			result=money-Math.floor(money/moneyCondition)*moneyReturn;
		}
		
		return result;
	}

}

而前端页面的那个选项变为:

<!-- 		<option value="StrategyCashNormal">正常收费</option>
		<option value="StrategyCashRebate">打8折</option>
		<option value="StrategyCashReturn">满300送100</option> -->

        跑到tomcat即可实现效果。

讲的可能不太好,可以来这里下载源码:源码下载

也可以来群与我交流:java修炼塔 535296702


阅读更多

没有更多推荐了,返回首页