一、模式定义
模板模式(Template Pattern)是一种行为设计模式,它在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。
二、模式动机
许多业务有着相同的算法/步骤骨架,这些算法/步骤中有许多是相同的实现要求,部分步骤是要求不同的实现。
此时就可以在超类/抽象类中定义算法和步骤,提供程序的方法主入口。由超类/抽象类来实现通用的步骤方法,超类/抽象类无法实现的具体步骤交给子类来实现。
三、模式结构
模板模式的角色:
- 抽象模板角色:抽象模板类,定义了一个具体的算法流程和一些留给子类必须实现的抽象方法。
- 具体子类角色:实现抽象模板类中的抽象方法,子类可以有自己独特的实现形式,但是执行流程受抽象模板类控制。
四、代码实现
加入有这样一个系统,该系统对外提供一系列不同的接口,例如天气预报系统,对外提供:
1、查询城市列表
2、查询某城市天气
3、…(等等不同性质的接口)
这些接口处理,无一例外都需要遵守相同的处理步骤:
1、验证来源是否合法
2、解密请求的报文
3、进行对应的业务处理
4、将业务处理返回的对象字符串进行加密
5、字符串进行加密后,再进加签
6、最后再返回给调用方加签后的结果
角色 | 类 |
---|---|
抽象模板角色 | AbstractTemplate.java |
具体子类角色 | BusinessA.java、BusinessC.java、BusinessC.java |
测试客户类 | ClientTest.java |
AbstractTemplate.java
package com.design.demo.behavior.template;
/**
* 接口抽象类
* 现实中的场景往往更复杂,出入参对象也通常不会是String类型
*
* @author administrator
* @date 2020-05-30 22:33
*/
public abstract class AbstractTemplate {
/**
* 入口方法
*
* @param str
* @return
*/
public String handle(String str) {
this.step1(str);//验证签名
String plainText = this.step2(str);//解密
String childResStr = this.busiHandle(plainText);//将解密后的报文交给子类去处理,并且得到子类返回的对象
String cipherText = this.step4(childResStr);//加密子类返回的内容
String resStr = this.step5(cipherText);//密文再加上签名
return resStr;//最后返回给调用方
}
/**
* 对报文进行验证签名,检查来源是否合法
*
* @param str
* @return
*/
private boolean step1(String str) {
//省略具体实现...
System.out.println("对请求对象:[" + str + "]校验来源是否合法!");
return true;
}
/**
* 对报文解密,得到明文报文
*
* @param str
* @return
*/
private String step2(String str) {
//省略具体实现...
System.out.println("对请求对象:[" + str + "]进行解密!");
String plainText = "明文" + str;
return plainText;
}
/**
* 对解密后的报文,进行业务处理,得到返回报文
*
* @param str
* @return
*/
protected abstract String busiHandle(String str);
/**
* 对要返回出去的报文进行加密,得到密文
*
* @param str
* @return
*/
private String step4(String str) {
//省略具体实现...
System.out.println("对返回对象:[" + str + "]进行加密!");
return str;
}
/**
* 对密文进行加签,得到含有签名的密文
*
* @param str
* @return
*/
private String step5(String str) {
//省略具体实现...
System.out.println("对返回对象:[" + str + "]进行加签名!");
return str;
}
}
BusinessA.java
package com.design.demo.behavior.template;
/**
* 遵守AbstractTemplate的其中一种业务实现
*
* @author administrator
* @date 2020-05-30 22:40
*/
public class BusinessA extends AbstractTemplate {
@Override
protected String busiHandle(String str) {
//我只需要做好关于BusinessA的实现就行了,其他相关的都是由父类去统筹
//省略具体实现...
String resStr = "BusinessA";
System.out.println("关于BusinessA的实现,入参内容:[" + str + "]出参内容:[" + resStr + "]");
return resStr;
}
}
BusinessB.java
package com.design.demo.behavior.template;
/**
* 遵守AbstractTemplate的其中一种业务实现
* @author administrator
* @date 2020-05-30 22:40
*/
public class BusinessB extends AbstractTemplate {
@Override
protected String busiHandle(String str) {
//我只需要做好关于BusinessA的实现就行了,其他相关的都是由父类去统筹
//省略具体实现...
String resStr = "BusinessB";
System.out.println("关于BusinessB的实现,入参内容:[" + str + "]出参内容:[" + resStr + "]");
return resStr;
}
}
BusinessC.java
package com.design.demo.behavior.template;
/**
* 遵守AbstractTemplate的其中一种业务实现
* @author administrator
* @date 2020-05-30 22:40
*/
public class BusinessC extends AbstractTemplate {
@Override
protected String busiHandle(String str) {
//我只需要做好关于BusinessA的实现就行了,其他相关的都是由父类去统筹
//省略具体实现...
String resStr = "BusinessC";
System.out.println("关于BusinessC的实现,入参内容:[" + str + "]出参内容:[" + resStr + "]");
return resStr;
}
}
ClientTest.java
package com.design.demo.behavior.template;
/**
* @author administrator
* @date 2020-05-30 22:55
*/
public class ClientTest {
public static void main(String[] args) {
String str1 = "业务1";
AbstractTemplate at1 = new BusinessA();
at1.handle(str1);
System.out.println("------------------------------");
String str2 = "业务2";
AbstractTemplate at2 = new BusinessB();
at2.handle(str2);
System.out.println("------------------------------");
String str3 = "业务3";
AbstractTemplate at3 = new BusinessC();
at3.handle(str3);
}
}
测试类运行结果