引入一个模板方法列子,我们经常写一些web工程,下面是我们常见的写代码的方式
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TestServlet
*/
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("hello");
}
}
测试结果
分析
父类定义了整个执行代码流程,而将细节实现部分延迟到子类,即父类定义模板,子类做填空处理(重新定义算法中的某些步骤,如上面输出hello)
模板方法模式
设计模式
templateMethod会调用privimitiveOperation1方法和privimitiveOperation2方法,也会调用其他方法,但是privimitiveOperation1方法和privimitiveOperation2方法是抽象方法
对应代码例子
父类抽象
package headfirst.hd.template.eg;
public abstract class AbstractClass {
//不让子类覆盖掉这个方法,声明为final类型
//父类定义程序执行模板
public final void templateMethod() {
init();
privimitiveOperation1(); //可以是任意位置
doSomeThing();
privimitiveOperation2(); //可以是任意位置
destroy();
}
//可以定义为private类型,对子类屏蔽
public void init() {
System.out.println("这是父类一个初始化init方法,需要做很多事情");
}
public void destroy() {
System.out.println("这是父类一个初始化destroy方法,需要做很多事情\n");
}
public void doSomeThing() {
System.out.println("做很多事情");
}
//一般抽象方法数据不是很多
public abstract void privimitiveOperation1();
public abstract void privimitiveOperation2();
}
子类实现
package headfirst.hd.template.eg;
public class ConcreteClass extends AbstractClass {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass,子类方法2,做了很多事情");
}
}
package headfirst.hd.template.eg;
public class ConcreteClass2 extends AbstractClass {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass2,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass2,子类方法2,做了很多事情");
}
}
测试代码Client
package headfirst.hd.template.eg;
public class Client {
//模板方法模式:定义程序执行流程,子类实现部分步骤
public static void main(String[] args) {
AbstractClass temlate = new ConcreteClass();
temlate.templateMethod();
//更换第二个子类,程序执行流程不变
temlate = new ConcreteClass2();
temlate.templateMethod();
}
}
测试结果
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass,子类方法1,做了很多事情
做很多事情
类ConcreteClass,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass2,子类方法1,做了很多事情
做很多事情
类ConcreteClass2,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
从上面例子总结
模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式与策略者模式区别
策略者模式入门:http://blog.csdn.net/dengjili/article/details/79273928
改写上面的例子
抽象变化部分
package headfirst.hd.template.stratagy;
public interface ChangeInterface {
void privimitiveOperation1();
void privimitiveOperation2();
}
实现算法变化部分
package headfirst.hd.template.stratagy;
public class ChangeImpl implements ChangeInterface {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass,子类方法2,做了很多事情");
}
}
package headfirst.hd.template.stratagy;
public class ChangeImpl2 implements ChangeInterface {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass2,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass2,子类方法2,做了很多事情");
}
}
载体代码
package headfirst.hd.template.stratagy;
public class ConcreteClass {
private ChangeInterface change;
public ConcreteClass(ChangeInterface change) {
this.change = change;
}
//不让子类覆盖掉这个方法,声明为final类型
public final void templateMethod() {
init();
change.privimitiveOperation1(); //可以是任意位置
doSomeThing();
change.privimitiveOperation2(); //可以是任意位置
destroy();
}
public void init() {
System.out.println("这是父类一个初始化init方法,需要做很多事情");
}
public void destroy() {
System.out.println("这是父类一个初始化destroy方法,需要做很多事情\n");
}
public void doSomeThing() {
System.out.println("做很多事情");
}
}
测试代码Client
package headfirst.hd.template.stratagy;
public class Client {
//策略者模式:子类选择具体的算法
public static void main(String[] args) {
//子类算法1
ChangeInterface change = new ChangeImpl();
ConcreteClass concrete = new ConcreteClass(change);
concrete.templateMethod();
//子类算法2
change = new ChangeImpl2();
concrete = new ConcreteClass(change);
concrete.templateMethod();
}
}
测试结果
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass,子类方法1,做了很多事情
做很多事情
类ConcreteClass,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass2,子类方法1,做了很多事情
做很多事情
类ConcreteClass2,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
比较
– | 模板方法 | 策略者模式 |
---|---|---|
用途区别 | 父类定义完成算法步骤,子类实现部分细节 | 子类决定如何实现算法步骤(一般是完整算法) |
实现方式 | 继承方式 | 组合方式 |
模板方法模式与工厂方法模式区别
实现方法相同,区别主要是用途上
– | 模板方法 | 工厂方法 |
---|---|---|
用途区别 | 父类定义完成算法步骤,子类实现部分细节 | 子类创建对象 |
模板方法在java中的应用 接口Comparable<T>
Arrays.sort()方法的应用:http://blog.csdn.net/dengjili/article/details/79646502
模板方法-高级应用 hook(钩子)
对应链接:https://blog.csdn.net/dengjili/article/details/79658547