设计模式(4)-模板方法模式详解(易懂)
模板方法模式定义
模板方法模式(Template Method Pattern):定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法是一种类行为型模式。
从模型图来看,模板方法模式很简单,但是很常用。抽象模板(AbstractClass)中的方法基本分两类:
-
基本方法:子类去实现的方法 ,并且在模板方法中被调用。
-
模板方法:把基本操作方法组合在一起形成一个总算法或一个总行为的方法;一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。
而具体模板(ConcreteClass)主要是实现父类定义的抽象的基本方法。
模板方法模式实例+扩展
例子:给两种手机做测试的,测试包括“开机,检查,关机”三种操作。下面用具体的代码来说明:
1.抽象类
public abstract class TestModel {
//开机
protected abstract void open();
//检查
protected abstract void check();
//关闭
protected abstract void close();
//模板方法-测试
public void test(){
this.open();;
this.check();
this.close();
}
}
2.两个实现类Phone1,Phone2
public class Phone1 extends TestModel {
@Override
protected void open() {
System.out.println("phone1的开机逻辑");
}
@Override
protected void check() {
System.out.println("phone1的检查逻辑");
}
@Override
protected void close() {
System.out.println("phone1的关机逻辑");
}
}
public class Phone2 extends TestModel {
@Override
protected void open() {
System.out.println("phone2的开机逻辑");
}
@Override
protected void check() {
System.out.println("phone2的检查逻辑");
}
@Override
protected void close() {
System.out.println("phone2的关机逻辑");
}
}
3.调用
TestModel testModel1=new Phone1();
TestModel testModel2=new Phone2();
testModel1.test();
testModel2.test();
运行的结果如下:
二.扩展
如果phone1在测试中需要关机,而phone2不需要关机,这时需要一个钩子方法。
1.抽象类
public abstract class TestModel {
//开机
protected abstract void open();
//检查
protected abstract void check();
//关闭
protected abstract void close();
//模板方法-测试
public void test(){
this.open();;
this.check();
if (isClose()){
this.close();
}
}
//钩子方法,默认是关机
protected boolean isClose(){
return true;
}
}
2.实现类
public class Phone1 extends TestModel {
public boolean isClose=true;
public void setIsClose(boolean isClose){
this.isClose=isClose;
}
protected boolean isClose(){
return this.isClose;
}
@Override
protected void open() {
System.out.println("phone1的开机逻辑");
}
@Override
protected void check() {
System.out.println("phone1的检查逻辑");
}
@Override
protected void close() {
System.out.println("phone1的关机逻辑");
}
}
public class Phone2 extends TestModel {
@Override
protected void open() {
System.out.println("phone2的开机逻辑");
}
@Override
protected void check() {
System.out.println("phone2的检查逻辑");
}
@Override
protected void close() {
System.out.println("phone2的关机逻辑");
}
//因为是取消关机,所以直接返回false就可以了
protected boolean isClose(){
return false;
}
}
3.调用
Phone1 testModel1=new Phone1();
Phone2 testModel2=new Phone2();
//phone1
testModel1.setIsClose(true);
testModel1.test();
//phone2
testModel2.test()
模板方法模式的优缺点及应用
1.优点
-
封装不变部分,扩展可变的部分。
-
提取了公共的代码,减少代码量,方便维护。
-
父类控制方法,子类去实现。
2.缺点
-
代码的阅读难度会增加,尤其是新手。我们习惯认为抽象类申明的是最抽象的、最一般的事物属性和方法,实现类完成具体的事物属性和方法;而在模板方法模式中,抽象类中定义了部分抽象方法,而子类实现父类后执行的结果影响了父类,子类对父类产生了影响。
3.应用
-
重构
-
规定算法
-
抽取公共的逻辑
参考资料《大话设计模式》《设计模式之禅》
推荐阅读