設計模式——模板模式
1- 模板模式定義
模板模式:所謂模板模式就是定義一個操作中的算法骨架,將多個實現類中相同的業務處理邏輯提取出來放在父類中,而將各個實現類中不同於其他實現類所獨特的業務邏輯放在具體的實現類中。模板方法可以使得子類可以不改變一個算法的結構即可重定義該算法的某些特定的步驟。
廢話不多說,Show Code!
請引入fastjson依賴,引入guava依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency>
2- 具體實現代碼
2-0準備工作
爲了更好的介紹模板模式,引入一些業務場景,定義兩個pojo:OrderMain,OrderDetail,定義一個工具類OperateUtil:
package designPattern.test.template.pojo;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* pojo
*/
public class OrderMain implements Serializable {
/**
* 主鍵
*/
private Long id;
/**
* 訂單號
*/
private String orderNo;
/**
* sku數
*/
private Integer skuQty;
/**
* 商品數
*/
private Integer goodsQty;
/**
* 金額
*/
private BigDecimal amount;
/**
* 生成時間
*/
private Date createTime;
/**
* 明細
*/
private List<OrderDetail> orderDetailList;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public Integer getSkuQty() {
return skuQty;
}
public void setSkuQty(Integer skuQty) {
this.skuQty = skuQty;
}
public Integer getGoodsQty() {
return goodsQty;
}
public void setGoodsQty(Integer goodsQty) {
this.goodsQty = goodsQty;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public List<OrderDetail> getOrderDetailList() {
return orderDetailList;
}
public void setOrderDetailList(List<OrderDetail> orderDetailList) {
this.orderDetailList = orderDetailList;
}
}
package designPattern.test.template.pojo;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 明細
*/
public class OrderDetail implements Serializable{
private Long id;
private String orderNo;
private String goodsNo;
private String goodsName;
private BigDecimal price;
private Integer qty;
private Date productionDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getGoodsNo() {
return goodsNo;
}
public void setGoodsNo(String goodsNo) {
this.goodsNo = goodsNo;
}
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getQty() {
return qty;
}
public void setQty(Integer qty) {
this.qty = qty;
}
public Date getProductionDate() {
return productionDate;
}
public void setProductionDate(Date productionDate) {
this.productionDate = productionDate;
}
}
package designPattern.test.template.commons;
/**
* 工具類
*/
public final class OperateUtil {
public static final String RESULT_CODE = "resultCode";
public static final String RESULT_VAULE = "resultValue";
}
2-1抽象類
將多個實現類中共同的業務邏輯提取出來放在抽象類,代碼如下:
package designPattern.test.template;
import com.alibaba.fastjson.JSON;
import designPattern.test.template.commons.OperateUtil;
import designPattern.test.template.pojo.OrderMain;
import java.util.HashMap;
import java.util.Map;
/**
* 抽象的操作類,將重複的代碼都放在這個抽象類中
*/
public abstract class AbstractOperate {
/**
* 此方法可以認爲是所有的具體的實現類都具有相同實現的方法
*拿到入參後解析成OrderMain進行操作
*/
public Map<String, Object> operate1(String msg) {
Map<String, Object> resultMap = new HashMap<>();
OrderMain orderMain = JSON.parseObject(msg, OrderMain.class);
//operate1具體的操作,可以是把數據落庫或其他
System.out.println(orderMain.getOrderNo() + ":" + orderMain.getSkuQty());
resultMap.put(OperateUtil.RESULT_CODE, Boolean.TRUE);
resultMap.put(OperateUtil.RESULT_VAULE, orderMain);
return resultMap;
}
/**
* 此方法可以認爲是所有的具體的實現類都具有不同實現的方法
* 具體的實現放在子類中
*/
public abstract void operate2(Map<String, Object> map);
/**
* 此方法可以認爲是所有的具體的實現類都具有不同實現的方法
* 具體的實現放在子類中
*/
public abstract void operate3(Map<String, Object> map);
public void operate4(String msg) {
//1-所有的實現類都相同的處理
Map<String, Object> resultMap = operate1(msg);
//2-抽象方法2,具體業務邏輯在子類中
operate2(resultMap);
//3-抽象方法3,具體業務邏輯在子類中
operate3(resultMap);
//4-所有實現類相同的結束處理邏輯
System.out.println("處理完成");
}
}
方法operate1可以認爲是所有子類都相同的業務邏輯!
方法operate2、operate3可以認爲是不同的實現類所特有的業務邏輯!
方法operate4可以認爲所有實現類都需要處理的業務邏輯,只是其中的某些部分不同的實現類有不同的業務邏輯!
2-2具體的實現類
1-北京實現類:BJOperate
package designPattern.test.template.opertates;
import designPattern.test.template.AbstractOperate;
import designPattern.test.template.commons.OperateUtil;
import designPattern.test.template.pojo.OrderMain;
import java.util.Date;
import java.util.Map;
/**
* 具體的實現類,各個地方有自己的處理方法,北京有北京的方法
*/
public class BJOperate extends AbstractOperate {
/**
* BJOperate具體的邏輯 operate2
*/
@Override
public void operate2(Map<String, Object> map) {
try {
Boolean resultCode = (Boolean) map.get(OperateUtil.RESULT_CODE);
if (resultCode) {
OrderMain orderMain = (OrderMain) map.get(OperateUtil.RESULT_VAULE);
System.out.println("北京純爺們!");
System.out.println("BJOperate orderNo:" + orderMain.getOrderNo() + "operate2 is operating!");
}else{
System.out.println("BJOperate resultCode is false");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* BJOperate具體的邏輯 operate3
*/
@Override
public void operate3(Map<String, Object> map) {
try {
Boolean resultCode = (Boolean) map.get(OperateUtil.RESULT_CODE);
if (resultCode) {
OrderMain orderMain = (OrderMain) map.get(OperateUtil.RESULT_VAULE);
Date createTime = orderMain.getCreateTime();
System.out.println("北京純爺們!");
System.out.println("BJOperate orderNo:" + orderMain.getOrderNo() + "createTime is " + createTime + "!");
System.out.println("BJOperate orderNo:" + orderMain.getOrderNo() + "operate3 is operating!");
} else{
System.out.println("BJOperate resultCode is false");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2-上海實現類:SHOperate
package designPattern.test.template.opertates;
import designPattern.test.template.AbstractOperate;
import designPattern.test.template.commons.OperateUtil;
import designPattern.test.template.pojo.OrderMain;
import java.util.Date;
import java.util.Map;
/**
* 上海的具體處理邏輯
*/
public class SHOperate extends AbstractOperate {
/**
* BJOperate具體的邏輯 operate2
*/
@Override
public void operate2(Map<String, Object> map) {
try {
Boolean resultCode = (Boolean) map.get(OperateUtil.RESULT_CODE);
if (resultCode) {
OrderMain orderMain = (OrderMain) map.get(OperateUtil.RESULT_VAULE);
//具體的不同邏輯
System.out.println("阿拉是上海人!");
System.out.println("SHOperate orderNo:" + orderMain.getOrderNo() + "operate2 is operating!");
} else{
System.out.println("SHOperate resultCode is false");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* BJOperate具體的邏輯 operate3
*/
@Override
public void operate3(Map<String, Object> map) {
try {
Boolean resultCode = (Boolean) map.get(OperateUtil.RESULT_CODE);
if (resultCode) {
OrderMain orderMain = (OrderMain) map.get(OperateUtil.RESULT_VAULE);
Date createTime = orderMain.getCreateTime();
//具體的不同邏輯
System.out.println("阿拉是上海人!");
System.out.println("SHOperate orderNo:" + orderMain.getOrderNo() + "createTime is " + createTime + "!");
System.out.println("SHOperate orderNo:" + orderMain.getOrderNo() + "operate3 is operating!");
}else{
System.out.println("SHOperate resultCode is false");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
如BJOperate、SHOperate所示,將抽象類中的抽象方法operate2、operate3的具體實現放在具體的實現類中。
3- 測試
package designPattern.test.template;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import designPattern.test.template.opertates.BJOperate;
import designPattern.test.template.opertates.SHOperate;
import designPattern.test.template.pojo.OrderDetail;
import designPattern.test.template.pojo.OrderMain;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 模板模式測試
*/
public class TemplateTest {
/**
* 測試北京
*/
@Test
public void testBJOperate() {
AbstractOperate operate = new BJOperate();
operate.operate4(testJson());
}
/**
* 測試上海
*/
@Test
public void testSHOperate() {
AbstractOperate operate = new SHOperate();
operate.operate4(testJson());
}
private String testJson() {
OrderMain orderMain = new OrderMain();
orderMain.setId(1l);
orderMain.setOrderNo("12345678");
orderMain.setSkuQty(2);
orderMain.setGoodsQty(3);
orderMain.setAmount(new BigDecimal(40));
orderMain.setCreateTime(new Date());
OrderDetail detail1 = new OrderDetail();
detail1.setId(1l);
detail1.setOrderNo(orderMain.getOrderNo());
detail1.setGoodsNo("1234001");
detail1.setGoodsName("ApplePhone");
detail1.setQty(1);
detail1.setPrice(new BigDecimal(20));
detail1.setProductionDate(new Date());
OrderDetail detail2 = new OrderDetail();
detail2.setId(2l);
detail2.setOrderNo(orderMain.getOrderNo());
detail2.setGoodsNo("1234002");
detail2.setGoodsName("HuaWeiPhone");
detail2.setQty(2);
detail2.setPrice(new BigDecimal(10));
detail2.setProductionDate(new Date());
List<OrderDetail> orderDetailList = Lists.newArrayList(detail1, detail2);
orderMain.setOrderDetailList(orderDetailList);
String s = JSON.toJSONString(orderMain);
return s;
}
}
總結:模板模式就是通過把不變的行爲搬移到父類中,各個子類獨特的行爲放在子類中的方式,最大限度的提高代碼的複用度,可以把更多的精力放在具體的子類中不同的獨特的處理邏輯上,相同的行爲如果需要修改則只需要修改父類中的代碼就行了!