什么是模板方法模式
定义一个操作中的算法骨架,而将一些步骤延迟到子类中去具体实现。模板方法可以使得子类不改变算法的结构就可以重新定义算法的某些特定步骤。
上面就是给出的比较官方的定义,读起来是有点绕口,不过个人认为定义的是非常的标准和仔细。不信你可以先看看下面的具体代码是怎么实现之后在回过头来品味。你品,你细品~~~
为什么要使用模板方法模式
学习一个设计模式,我们都会问这么写有什么意义呢?为什么这么写,就是很牛逼的呢?我不这样写咋的啦,我的代码还不是可以直接运行起来。对对对,你说的都对,但是您的代码真的就很好维护了吗,真的就好扩展了吗?不信我举一个下面的例子,看看这是不是你写的那种(●’◡’●)
业务背景:
咱们说一说炒蛋炒饭过程,现在Smile饭馆有2种等级厨师,皇家厨师的手法可以炒出传说中的黄金炒饭,普通厨师只能炒出普通的蛋炒饭。但是炒蛋炒饭都是需要鸡蛋,需要盐,需要热锅,需要出锅等等这一系列的操作,不管你是什么级别的厨师,这些基本操作都是一样的。(以上为业务背景)
一般的写法:
package com.zxy.template;
public class YouCook {
public void cook(String name){
System.out.println("准备鸡蛋....");
System.out.println("鸡蛋中放盐....");
System.out.println("打开灶炉.....");
if(name.equals("皇家厨师")){
System.out.println(name+"---开始制作蛋炒饭...");
System.out.println("油温80°,先下米饭...");
System.out.println("一分钟后倒入鸡蛋液...");
System.out.println("翻炒翻炒,再翻炒,撒上一点葱花隔壁小孩都馋哭了(●'◡'●)");
}
if(name.equals("普通厨师")){
System.out.println(name+"---开始制作蛋炒饭...");
System.out.println("油温冒烟就行,倒入鸡蛋液.....");
System.out.println("看心情加入米饭.....");
System.out.println("炒一下就行了,意思意思....(●'◡'●)");
}
System.out.println("关闭灶炉.....");
System.out.println("起锅咯....");
}
public static void main(String[] args) {
YouCook youCook = new YouCook();
youCook.cooking("皇家厨师");
System.out.println();
youCook.cooking("普通厨师");
}
}
运行结果:
乍一看好像你会想,嗯,很不错嘛,这样问题不大噻。不也是实现了这个功能吗?那你这个设计模式有啥diao用?现在我们思考一个问题,if 语句里面的代码是我们的核心业务代码,这个是体现了我们代码的最主要的逻辑。当随着系统的不断扩大,可能有一天会说准备鸡蛋的时候,要打鸡蛋液,要洗锅,结束了之后也还要洗锅,洗锅铲等等。那么我们就会在核心业务代码的前面再加上准备工作代码,在核心业务代码后面再加上结束操作代码。久而久之,这个方面里面核心业务逻辑的代码,被沉静在了这些不重要的像是在玩套路的代码中,不免得会显得有点喧宾夺主的味道,不利于后期得维护。
如何使用
那么我们该怎么做呢?我们的代码还有救吗?不要慌,那肯定是必须能救的呀(●’◡’●)
接下来看看使用模板方法模式后代码的改变
- 首先咱们定义一个抽象类,表示烹饪的整个过程
public abstract class Cook {
private void prepareEgg(){
System.out.println("准备鸡蛋....");
}
//定义好整个算法的框架,该怎么一步一步的完成蛋炒饭的过程
public final void cook(){
prepareEgg();;
prepareSalt();
fire();
cooking();
closeFire();
out();
}
private void prepareSalt(){
System.out.println("鸡蛋中放盐....");
}
private void fire(){
System.out.println("打开灶炉.....");
}
//这里是我们的核心业务逻辑,交给具体的子类去实现它的定制吧
public abstract void cooking();
private void closeFire(){
System.out.println("关闭灶炉.....");
}
private void out(){
System.out.println("起锅咯....");
}
}
- 皇家厨师类(皇家级厨师)
//皇家级厨师
public class RoyalCook extends Cook{
private String name = "皇家厨师";
//我只关注怎么炒饭呢,其他的我不管
@Override
public void cooking() {
System.out.println(name+"---开始制作蛋炒饭...");
System.out.println("油温80°,先下米饭...");
System.out.println("一分钟后倒入鸡蛋液...");
System.out.println("翻炒翻炒,再翻炒,撒上一点葱花隔壁小孩都馋哭了(●'◡'●)");
}
}
- 普通厨师类(普通厨师)
//普通厨师
public class NormalCook extends Cook{
private String name = "普通厨师";
@Override
public void cooking() {
System.out.println(name+"---开始制作蛋炒饭...");
System.out.println("油温冒烟就行,倒入鸡蛋液.....");
System.out.println("看心情加入米饭.....");
System.out.println("炒一下就行了,意思意思....(●'◡'●)");
}
}
- 测试
public class CookTest {
public static void main(String[] args) {
RoyalCook royalCook = new RoyalCook();
royalCook.cook();
NormalCook normalCook = new NormalCook();
System.out.println();
normalCook.cook();
}
}
- 运行结果:
类图关系
总结
总结?再细细品味一下它的定义吧!定义一个操作中的算法骨架,而将一些步骤延迟到子类中去具体实现。模板方法可以使得子类不改变算法的结构就可以重新定义算法的某些特定步骤,现在是不是有内味儿了呢?🤭,感谢今天的这碗蛋炒饭,让我们又学习到一种设计模式。
最后,如果文章中存在不足的方法,欢迎各位留言指正。
上一篇:Java-设计模式之单例模式