共计 3311 个字符,预计需要花费 9 分钟才能阅读完成。
开局还是那种图,各位客官往下看 …
张无忌学太极拳,遗记了所有招式,打倒了 ” 玄冥二老 ”,所谓 ” 心中无招 ”。设计模式堪称招数,如果先学通了各种模式,又忘掉了所有模式而得心应手,堪称 OO 之最高境界。
模板模式是什么?
模板模式,同样是一种行为型模式,也就是对于 对象做什么或者怎么做 的设计模式。模板模式的实质须要定义操作中的算法的框架,然而有一些步骤,又不须要具体的实现,而是不同的子类各自实现。子类不能批改流程框架,然而局部的步骤能够做定制化的实现。
次要要解决一个问题:一些通用的办法,然而每一个子类却都从新写,冗余。
比如说,做菜的步骤个别是:洗锅 --> 炒菜 --> 洗碗
,不同的菜,只是炒菜这一个步骤具体细节是不同的,然而其余步骤的确简直截然不同的,这样其实整体框架,以及反复的步骤,咱们能够形象到模板中,而不同的细节办法能够凋谢给每一种菜(具体实现)去定制。
又比方造房子的时候,很多中央的建造都是一样的:地基,墙壁,水管等等,然而不同的房子外面的外部的设计又有所不同。
不应用模板模式
就挑个简略的例子“炒菜”,如果不应用模板模式的话,糖醋鲤鱼:
public class SweetAndSourCarp {public void cookFood(){washPan();
cook();
eat();
washDishes();
System.out.println("");
}
private void washPan(){System.out.print("洗锅 -->");
}
private void cook(){System.out.print("煮糖醋鲤鱼 -->");
}
private void eat(){System.out.print("吃饭 -->");
}
private void washDishes(){System.out.print("洗碗 -->");
}
}
再弄一个农家小炒肉,须要写很多雷同的办法:
public class ShreddedPorkWithVegetables {public void cookFood(){washPan();
cook();
eat();
washDishes();
System.out.println("");
}
private void washPan(){System.out.print("洗锅 -->");
}
private void cook(){System.out.print("炒农家小炒肉 -->");
}
private void eat(){System.out.print("吃饭 -->");
}
private void washDishes(){System.out.print("洗碗 -->");
}
}
测试类如下:
public class Test {public static void main(String[] args) {SweetAndSourCarp sweetAndSourCarp = new SweetAndSourCarp();
sweetAndSourCarp.cookFood();
ShreddedPorkWithVegetables shreddedPorkWithVegetables = new ShreddedPorkWithVegetables();
shreddedPorkWithVegetables.cookFood();}
}
测试后果:
洗锅 --> 煮糖醋鲤鱼 --> 吃饭 --> 洗碗 -->
洗锅 --> 炒农家小炒肉 --> 吃饭 --> 洗碗 -->
能够看到,整体流程是一样的,有些步骤一样,有些步骤不一样,然而不应用模板模式,须要每个类都重写一遍办法,即便是通用办法,整个流程都须要本人写一遍。
应用模板模式优化
如果应用模板模式,那么咱们会形象出一个抽象类,定义整体的流程,曾经固定的步骤,凋谢须要定制的办法,让具体的实现类依照本人的需要来定制。
定义的抽象类:
public abstract class CookFood {public final void cookFood() {washPan();
cook();
eat();
washDishes();
System.out.println("");
}
private final void washPan() {System.out.print("洗锅 -->");
}
public abstract void cook();
private final void eat() {System.out.print("吃饭 -->");
}
private final void washDishes() {System.out.print("洗碗 -->");
}
}
具体的实现类糖醋鲤鱼:
public class SweetAndSourCarp extends CookFood {
@Override
public void cook() {System.out.print("煮糖醋鲤鱼 -->");
}
}
农家小炒肉:
public class ShreddedPorkWithVegetables extends CookFood {
@Override
public void cook() {System.out.print("炒农家小炒肉 -->");
}
}
测试类与后面的一样,测试后果也一样,这里不再反复。
下面的办法中,其实咱们只凋谢了 cook()
办法,这就是 钩子办法:
在模板办法模式的父类中,咱们能够定义一个办法,它默认不做任何事,子类能够视状况要不要笼罩它,该办法称为”钩子办法”
钩子办法是凋谢的,能够由子类随便笼罩,然而像下面的其余办法,咱们不心愿子类重写或者笼罩它,就能够用 final
关键字,避免子类重写模板办法。
模板模式的利用
其实在 JDK
的 Thread
实现中,就是应用了模板模式,咱们晓得创立线程有两个形式:
- 创立
Thread
类 - 实现
runnable
接口
咱们实现的个别是 run()
办法, 然而调用的却是 start()
办法来启动线程,这个起因就是 start()
办法外面帮咱们调用了 run()
办法,run()
办法是开发的办法,咱们能够笼罩重写它。
Start0()
是一个 native
办法,是由 c 语言去实现的,在调用的时候,真正调用了咱们的 run()
办法,如果须要跟踪这个办法须要到 HotSpot
底层去。这里介绍的目标是让大家理解,它同样是应用了模板模式。
private native void start0();
理解 native
关键字能够参考:http://aphysia.cn/archives/na…
模板模式的优缺点
模板模式的 长处:
- 1、封装固定的局部,拓展须要定制批改的局部,合乎开闭准则。
- 2、公共的代码在父类中,容易保护。
- 3、整个流程由父类把握,调整比拟不便。
毛病:
- 1、子类可能会很多,零碎复杂度回升。
- 2、子类只有一小部分实现,理解全副办法则须要在父类中浏览,影响代码浏览。
总结:代码该暗藏的简单细节暗藏起来,凋谢定制化局部,优雅!
设计模式系列:
- 设计模式【1】– 单例模式到底几种写法?
- 设计模式【1.1】– 你想如何毁坏单例模式?
- 设计模式【1.2】– 枚举式单例有那么好用么?
- 设计模式【1.3】– 为什么饿汉式单例是线程平安的?
- 设计模式【2】– 简略工厂模式理解一下?
- 设计模式【2.1】– 简略工厂模式怎么演变成工厂办法模式?
- 设计模式【2.2】– 工厂模式怎么演变成形象工厂模式?
- 设计模式【3.1】– 浅谈代理模式之动态、动静、cglib 代理
- 设计模式【3.2】– JDK 动静代理源码剖析有多香?
- 设计模式【3.3】– CGLIB 动静代理源码解读
- 设计模式【4】– 建造者模式详解
- 设计模式【5】– 原型模式
- 设计模式【6.1】– 初探适配器模式
- 设计模式【6.2】– 再聊聊适配器模式
- 设计模式【7】– 摸索一下桥接模式
- 设计模式【8】– 手工耿教我写装璜器模式
- 设计模式【9】– 外观模式?没那么高大上
- 设计模式【10】– 顺便看看享元模式
- 设计模式【11】– 搞定组合模式
- 设计模式【12】– 搞定最近大火的策略模式
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,集体网站:http://aphysia.cn,技术之路不在一时,山高水长,纵使迟缓,驰而不息。
剑指 Offer 全副题解 PDF
开源编程笔记