设计模式-简单工厂设计模式与策略模式之java实现
好久没写博客了!因为一直在看书,前不久看完了Java Core Technology II大多数章节的内容(除了gui那几章没咋看),如今正在看程杰的大话设计模式,这几个晚上都在用java来实现简单工厂模式与策略模式,并实现了其中的案例“超市商场促销”(虽然书也有源码,但是是用C#写的,客户端用的winform,虽然我以前就是干C#的,不过,早已经金盆洗手转行了!)
闲话不多说,先介绍一下场景“商场经常有促销活动,其促销方案有以下几种:1:不做任何促销,原价卖;2:打折销售,这里我们暂且指定为8折;3:满多少元返利多少元,这里我们暂且指定为满300返回100”。这里我不打算介绍太多关于设计模式的相关理论内容,具体可以参考这条链接,我觉得很不错:设计模式。
业务逻辑代码那块传统做法是用多重分支(if else...;switch..case)是判断采用了哪一种促销方案,但很明显这种设计很不符合软件设计的可重用,可复用,灵活,低耦合的原则,而且如果促销方案多了,那一坨代码看起来会很让人不爽,显得相当笨重!
于是乎出现了简单工厂设计模式,其实,我的理解就是它就是有一个专门用于造对象的工厂。而这里的对象,其实就是我们上面所说的各种促销方案,这几种方案有一个共同点就是“付费”!于是乎,按照自己的理解,我就写了一下的代码。先看看我的项目的总体结构(这里我就不打算用ssh或者ssm了,用jsp,servlet即可!)
先把各种方案对象与它们的接口贴出来先:
接口IStrategyCash :
package com.strategy;
public interface IStrategyCash {
double getResult(double money);
}
“正常收费”对象StrategyCashNormal :
package com.strategy;
public class StrategyCashNormal implements IStrategyCash {
@Override
public double getResult(double money) {
return money;
}
}
“打8折”对象StrategyCashRebate :
package com.strategy;
public class StrategyCashRebate implements IStrategyCash {
//打折: 8折---0.8
private double moneyRebate=1.0;
public StrategyCashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
public double getMoneyRebate() {
return moneyRebate;
}
public void setMoneyRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double getResult(double money) {
return money*moneyRebate;
}
}
“
满300返100”对象 StrategyCashReturn
package com.strategy;
public class StrategyCashReturn implements IStrategyCash {
//返利收费: 满300返100---moneyCondition=300 moneyReturn=100
private double moneyCondition=0.0;
private double moneyReturn=0.0;
public StrategyCashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
public double getMoneyCondition() {
return moneyCondition;
}
public void setMoneyCondition(double moneyCondition) {
this.moneyCondition = moneyCondition;
}
public double getMoneyReturn() {
return moneyReturn;
}
public void setMoneyReturn(double moneyReturn) {
this.moneyReturn = moneyReturn;
}
@Override
public double getResult(double money) {
double result=money;
if (money>=moneyCondition) {
result=money-Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
接下来,先贴出web.xml,后面介绍策略模式时,就不用再贴了!
javaDesignMode
strategyCodeServlet
com.designModeServlet.StrategyCodeServlet
strategyCodeServlet
/strategyMode
strategyCodeServlet2
com.designModeServlet.StrategyCodeServlet2
strategyCodeServlet2
/strategyMode2
strategyCodeServlet3
com.designModeServlet.StrategyCodeServlet3
strategyCodeServlet3
/strategyModeReflect
接下来当然是介绍一下造对象的工厂SimpleFactoryMode.java:
package com.simpleFactoryMode;
import com.strategy.IStrategyCash;
import com.strategy.StrategyCashNormal;
import com.strategy.StrategyCashRebate;
import com.strategy.StrategyCashReturn;
/**
* 简单工厂模式:造出收费的实例
* @author zhonglinsen
*
*/
public class SimpleFactoryMode {
/**
* 获取收费实例
* @param mode 选取模式(收费的方式)
* @param money 当前本应收费
* @param rebate 打折策略的打折
* @param moneyCondition 返利策略的满额
* @param moneyReturn 返利策略的返额
* @return
*/
public static IStrategyCash getCashResultStrategy(String mode,String money,String rebate,String moneyCondition,String moneyReturn){
IStrategyCash strategy=null;
switch (mode) {
case "1":
//正常收费
strategy=new StrategyCashNormal();
break;
case "2":
//打折
strategy=new StrategyCashRebate(Double.parseDouble(rebate));
break;
case "3":
//返利
strategy=new StrategyCashReturn(Double.parseDouble(moneyCondition), Double.parseDouble(moneyReturn));
break;
default:
break;
}
return strategy;
}
}
顺便把工具类ResponseUtil贴出来吧(用于当在js调用后台代码,后台处理完毕后将结果写回Js中):
package com.util;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
/**
* 将后台处理完的结果写回前端页面,如jsp页面;
* 或者可用于在ajax异步调用后台方法,该方法处理完相应业务逻辑之后将结果返回,这个结果即通过这个工具类实现
* @author 钟林森
*/
public class ResponseUtil {
public static void write(HttpServletResponse response,Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println(o.toString());
out.flush();
out.close();
}
}
完了之后,当然是后台Servlet的处理逻辑了StrategyCodeServlet.java(当然了,需要用到相关的jar,放在web-inf下的lib内,可以来这里下载: ):
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.SimpleFactoryMode;
import com.strategy.IStrategyCash;
import com.util.ResponseUtil;
/**
* 策略模式前奏-简单工厂模式
* @author zhonglinsen
*
*/
public class StrategyCodeServlet 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");
IStrategyCash strategyCash=SimpleFactoryMode.getCashResultStrategy(mode, money, rebate, moneyCondition, moneyReturn);
double cashResult=strategyCash.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);
}
}
最后是前端了,用的是jsp,页面就简单制作了,在这里需要用到jquery相关js库,自己去下载即可
cash.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
收费台
总费用:
优惠方式:
/**
*
*/
$(function(){
//简单工厂模式
$("#getCash").bind("click",function(){
var money=$('#cashText').val();
var mode=$("#strategy").val();
if (money=="" || mode=="") {
return;
}
console.log(money+" -- "+mode);
//简单工厂模式
$.post("strategyMode",{mode:mode,money:money,rebate:0.8,moneyCondition:300,moneyReturn:100},function(data){
console.log("返回结果:"+data.cashResult);
$('#divResult').css("display","");
$('#cashResult').html(data.cashResult);
},"json");
});
//策略模式
$("#getCash2").bind("click",function(){
var money=$('#cashText').val();
var mode=$("#strategy").val();
if (money=="" || mode=="") {
return;
}
console.log(money+" -- "+mode);
//简单工厂模式
$.post("strategyMode",{mode:mode,money:money,rebate:0.8,moneyCondition:300,moneyReturn:100},function(data){
console.log("返回结果:"+data.cashResult);
$('#divResult').css("display","");
$('#cashResult').html(data.cashResult);
},"json");
});
//策略模式
$("#getCash3").bind("click",function(){
var money=$('#cashText').val();
var mode=$("#strategy").val();
if (money=="" || mode=="") {
return;
}
console.log(money+" -- "+mode);
/* 简单工厂模式+策略模式+反射*/
$.post("strategyModeReflect",{mode:mode,money:money,rebate:0.8,moneyCondition:300,moneyReturn:100},function(data){
console.log("返回结果:"+data.cashResult);
$('#divResult').css("display","");
$('#cashResult').html(data.cashResult);
},"json");
});
});
好了,先简单介绍到这里吧,下一篇介绍剩下的东西,并打算将源码贡献给诸位!希望可以借此抛砖引玉,如果
想与我交流的,可以 加这个群535296702 “java修炼塔”。欢迎向我 索取源码跟交流!