模板模式是一种行为设计模式,它定义了一个算法的框架,把一些步骤推迟到子类中实现。
这个模板的本身并不实现这些步骤,而是提供了一些列抽象方法,让子类来实现这些抽象方法。这样做的好处是可以在不修改算法的情况下,通过不同子类的实现方法,扩展算法的行为。此外,模板模式还可以用来遵循“开闭原则”,将不同的行为封装在子类中,使得父类可以保持稳定,而子类可以灵活扩展。
场景
在大量重复的业务逻辑中,通过将公共的部分抽象成一个模板方法来避免代码重复。为防止恶意操作,一般模板方法都会加上 final
关键词。
优点
缺点
以医院看病为例:
比如去医院看病,挂号和排队这两个步骤是固定的,不管是什么病到了医院都得遵循这两个步骤;但是后续的检查和治疗这两个步骤是变化的,不同的病需要采用不同的检查方式,然后采取不同的治疗手段。
1.定义抽象疾病
/**
* 疾病
*/
public abstract class Disease {
/**
* 治病
*/
public void cure() {
// 1、挂号
registered();
// 2、排队
queue();
// 3、检查
check();
// 4、治疗
treat();
}
/**
* 挂号
*/
public void registered() {
System.out.println("1、挂号");
}
/**
* 排队
*/
public void queue() {
System.out.println("2、排队");
}
/**
* 检查
*/
public abstract void check();
/**
* 治疗
*/
public abstract void treat();
}
2.定义具体疾病
① 感冒
/**
* 感冒
*/
public class Cold extends Disease {
@Override
public void check() {
System.out.println("3、感冒检查:量体温");
}
@Override
public void treat() {
System.out.println("4、感冒开药:感冒灵");
}
}
① 口腔溃疡
/**
* 口腔溃疡
*/
public class MouthUlcers extends Disease {
@Override
public void check() {
System.out.println("3、口腔溃疡检查:看口腔");
}
@Override
public void treat() {
System.out.println("4、口腔溃疡开药:西瓜霜");
}
}
3.调用
public class Client {
public static void main(String[] args) {
// 感冒
Disease cold = new Cold();
// 口腔溃疡
Disease mouthUlcers = new MouthUlcers();
// 治疗感冒
cold.cure();
// 治疗口腔溃疡
mouthUlcers.cure();
}
}
控制台输出:
1、挂号
2、排队
3、感冒检查:量体温
4、感冒开药:感冒灵
1、挂号
2、排队
3、口腔溃疡检查:看口腔
4、口腔溃疡开药:西瓜霜
可以发现,在治疗感冒和口腔溃疡这两种疾病时,前两个步骤是一样的,只有后两个步骤是不同的,这样就实现了复用相同的步骤,后续再定义其他疾病时只需要继承 Disease 实现其抽象方法即可,复用性和扩展性都大大提高。