近日在项目开发中看到一段代码不理解,在方法中居然调用抽象方法。后来在网上查说是模板模式,
百思不得其解,最终在同事的指点下想起了一个很基础的东西:那就是抽象类是不能被实例化的!!!,
那为啥要这样写呢,就是为了实现部分定制化。
public abstract class JWBaseProcess implements JWProcess { protected JWBaseProcess() { try { workitemManager = WAPIFactory.getWorkItemManager(JWConstants.FLOW_TASK); } catch (BPMException e) { e.printStackTrace(); } } protected abstract void prefetchData(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception; public void prefetchWorkItemData(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception { //为页面显示准备数据 prefetchData(request, popForm, user); } protected abstract void beforeFinishProcess(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception; public void beforeFinishWorkItem(HttpServletRequest request, PrdOnlineProcessForm popForm,UserInfo user) throws Exception { //保存下节点执行人(通用部分) save(Person person); beforeFinishProcess(request, popForm,user);//在抽象类的子类的方法beforeFinishProcess中写定制化部分 } protected abstract void afterFinishProcessForward(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception; public void afterFinishProcessBack(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception { } public void afterFinishWorkItem(HttpServletRequest request, PrdOnlineProcessForm popForm, UserInfo user) throws Exception { //保存批注 if (jiVo.getLinkId() != null && jiVo.getLinkId().startsWith(PrdOnlineConstants.PRDONLINE_LINKID_BACK_PRE)) { afterFinishProcessBack(request, popForm, user); } else { afterFinishProcessForward(request, popForm, user); } } protected abstract void saveFinishProcess(PrdOnlineProcessForm popForm, UserInfo user) throws Exception; public void saveFinishWorkItem(PrdOnlineProcessForm popForm, UserInfo user) throws Exception { saveFinishProcess(popForm, user); } public String checkProcessData(PrdOnlineProcessForm popForm, UserInfo user) throws Exception { return PrdOnlineConstants.PRDONLINE_CHECKDATA_RETURN_VALUE_SUCCESS; } protected void getPrdOnlinePrdInfo(PrdOnlinePrdInfoVo piVo, PrdOnlineAcceptProcessVo acceVo, PrdOnlineAccountProcessVo accoVo, PrdOnlineNoticeProcessVo notiVo, PrdOnlineParameterProcessVo paraVo, PrdOnlineBillProcessVo billVo, String code) { //获取各个流程信息 } }
设计模式之模板模式
模板方法模式:模板方法模式准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
开闭原则是指一个软件实体应该对扩展开放,对修改关闭。也就是说软件实体必须是在不被修改的情况下被扩展。
模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则!
我们结合上面的定义解释一下该图。
- AbstractClass便相当于上述作为抽象类的父类,ConcreteClass便是具体的实现子类。具体的应用中,可能存在一到多个实现子类。
- AbstractClass定义了一个public的templateMethod()模板方法以及作为步骤的method1()与method2()方法。
- AbstractClass#templateMethod()方法体调用method1()与method2()方法
public void templateMethod() {
...
this.method()1;
...
this.method()2;
...
}
- method1()与method2()方法为受保护的抽象方法(protected abstract)。实现子类ConcreteClass需要重载该方法。
Template Method模式的应用场景:
Template Method模式一般应用在具有以下条件的应用中:
- 具有统一的操作步骤或操作过程
- 具有不同的操作细节
- 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
我们应该能够找到实现一件事情的相同的部分和不相同的部分各是什么:
举个简单的例子吧:比如说生产手机:生产的流程是相同的但是具体的细节可能有所不同(比如手机的颜色,手机的类别,手机的大小等等);
我们就用代码来实现这个小小的例子:
首先要创建一个抽象的模板类:
package TemplateDemo; /** * 这是一个抽象的模板类 * */ abstract class AbstractClass { //定义一个模板方法来控制生产手机的流程 public void makeMobile(){//TemplateMethod //首先生产手机体(模板方法自己完成) System.out.println("生产了一个手机body"); this.makeDifferentFunction(); this.makeDifferentColor(); this.makeDifferentType(); System.out.println("一部手机制作完成"); //以上模板已经规定好了 } //定义抽象的方法来完成不同的生产细节(不同功能的手机) protected abstract void makeDifferentFunction(); //定义抽象的方法来完成不同的生产细节(不同颜色的手机) protected abstract void makeDifferentColor(); //定义抽象的方法来完成不同的生产细节(不同类型的手机) protected abstract void makeDifferentType(); } /** * 创建真是的实现类来实现具体的生产细节 * */ class ConcreteClass extends AbstractClass{ //实现父类中的抽象的方法 protected void makeDifferentColor() { System.out.println("给该手机的颜色涂成蓝色"); } protected void makeDifferentFunction() { System.out.println("给该手机实现看MP4的功能"); } protected void makeDifferentType() { System.out.println("给该手机制作成翻盖的"); } } //写测试类 public class TestTemplate{ public static void main(String args[]){ AbstractClass ac = new ConcreteClass();//子类的对象付给父类 ac.makeMobile();//制作手机 //制作不同的手机只是修改子类就可以了 } }
想要完成不同的实现细节的话就只是再写不同的子类就是了,模板已经规定好了实现的流程!
这样一个简单的模板方法模式的实例就完成了!