您的位置:首页 > 编程语言 > Java开发

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

2016-12-16 22:30 831 查看
设计模式-简单工厂设计模式与策略模式之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,后面介绍策略模式时,就不用再贴了!
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>javaDesignMode</display-name>

<servlet>
<servlet-name>strategyCodeServlet</servlet-name>
<servlet-class>com.designModeServlet.StrategyCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>strategyCodeServlet</servlet-name>
<url-pattern>/strategyMode</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>strategyCodeServlet2</servlet-name>
<servlet-class>com.designModeServlet.StrategyCodeServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>strategyCodeServlet2</servlet-name>
<url-pattern>/strategyMode2</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>strategyCodeServlet3</servlet-name>
<servlet-class>com.designModeServlet.StrategyCodeServlet3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>strategyCodeServlet3</servlet-name>
<url-pattern>/strategyModeReflect</url-pattern>
</servlet-mapping>

</web-app>接下来当然是介绍一下造对象的工厂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"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>收费台</title>
<script type="text/javascript" src="js/jquery-1.7.2.js"></script>
<script type="text/javascript" src="js/getCash.js"></script>

</head>
<body>

总费用: <input type="text" id="cashText"  onKeypress="return (/[\d.]/.test(String.fromCharCode(event.keyCode)))"/>
<br><br>
优惠方式:
<select id="strategy">
<option value="1">正常收费</option>
<option value="2">打8折</option>
<option value="3">满300送100</option>
<!-- <option value="StrategyCashNormal">正常收费</option>
<option value="StrategyCashRebate">打8折</option>
<option value="StrategyCashReturn">满300送100</option> -->
</select>
<br><br>
<input type="button" id="getCash" value="收费-简单工厂模式" style="width: 160px;height: 25px"/>  
<input type="button" id="getCash2" value="收费-策略模式" style="width: 160px;height: 25px"/>  
<input type="button" id="getCash3" value="收费-策略模式+反射" style="width: 190px;height: 25px"/>  

<br><br>
<div id="divResult" style="display:none;color: red">
需要收费: <span id="cashResult"></span>
</div>

</body>
</html>




getCash.js:

/**
*
*/

$(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");
});

});



由于篇幅问题,策略模式与反射下一篇再贴出来!

现在放到tomcat跑起来,下面是运行结果:







      好了,先简单介绍到这里吧,下一篇介绍剩下的东西,并打算将源码贡献给诸位!希望可以借此抛砖引玉,如果

想与我交流的,可以 加这个群535296702 “java修炼塔”。欢迎向我 索取源码跟交流!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息