只有光头才能变强。java
文本已收录至个人GitHub仓库,欢迎Star:github.com/ZhongFuChen…git
在上一篇有读者说,一分钟就看完门面模式了,因此今天的标题就取《一分钟学会模板方法模式》github
回顾前面所写过的设计模式:面试
不管是面试仍是我的的提高,设计模式是必学的。今天来说解模板方法模式~算法
你们都知道,我每次写原创技术文章,开头总会有“只有光头才能变强”。我固然不可能每次写文章的时候都去复制这句话(由于这样太麻烦了)。设计模式
我有本身的写做模板,给你们看一下:框架
前言和最后都是固定下来的,至于第一点和第二点就得看是写什么文章,写不一样的文章对应的内容也是不同的。ide
每次我写文章的时候,只要在这个模板上添加我本身想写的东西就行了,就不用每次都复制一遍相同的内容,这样就大大减小个人工做量啦。ui
代码来源于生活,一样地我能够将我写文章的过程用代码来描述,你们来看一下。spa
3y每篇文章都会有“前言”和“最后”的内容,3y把这两个模块写出来了。
// 3y的文章模板
public class Java3yWriteArticle {
// 前言
public void introduction() {
System.out.println("只有光头才能变强");
}
// 最后
public void theLast() {
System.out.println("关注个人公众号:Java3y");
}
}
复制代码
3y写文章的时候,3y可能就会这样使用:
// 3y写文章
public static void main(String[] args) {
Java3yWriteArticle writeArticle = new Java3yWriteArticle();
// 前言
writeArticle.introduction();
// 实际内容
System.out.println("你们好,我是3y,今天来给你们分享我写的模板方法模式");
// 最后
writeArticle.theLast();
}
复制代码
这样是能够完成3y写文章的功能,可是这样作好吗?这时候3y女友也想写文章,她的文章一样也想有“前言”和“最后”两个模块,因此3y女友的文章模板是这样的:
// 3y女友的文章模板
public class Java3yGFWriteArticle {
// 前言
public void introduction() {
System.out.println("balabalabalalabalablablalab");
}
// 最后
public void theLast() {
System.out.println("balabalabalalabalablablalab");
}
}
复制代码
那3y女友写文章的时候,可能也会这样使用:
// 3y女友写文章
public static void main(String[] args) {
Java3yGFWriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();
// 前言
java3yGFWriteArticle.introduction();
// 实际内容
System.out.println("3y是傻子,不用管他");
// 最后
java3yGFWriteArticle.theLast();
}
复制代码
能够发现3y和3y女友要写文章的时是要重复调用introduction();
和theLast();
。而且,3y的文章模板和3y女友的文章模板中的“前言”和“最后”只是实现内容的不一样,却定义了两次,明显就是重复的代码。面对重复的代码咱们会作什么?很简单,抽取出来!
因而咱们就能够抽取出一个通用的WriteArticle(为了方便调用,咱们还将写文章的步骤封装成一个方法):
// 通用模板
public abstract class WriteArticle {
// 每一个人的“前言”都不同,因此抽象(abstract)
protected abstract void introduction();
// 每一个人的“最后”都不同,因此抽象(abstract)
protected abstract void theLast();
// 实际要写的内容,每一个人的“实际内容”都不同,因此抽象(abstract)
protected abstract void actualContent();
// 写一篇完整的文章(为了方便调用,咱们将这几个步骤分装成一个方法)
public final void writeAnCompleteArticle() {
// 前言
introduction();
// 实际内容
actualContent();
// 最后
theLast();
}
}
复制代码
因此,3y的模板就能够继承通用模板,在通用模板上实现本身想要的就行了:
// 3y的文章模板
public class Java3yWriteArticle extends WriteArticle {
// 前言
@Override
public void introduction() {
System.out.println("只有光头才能变强");
}
// 最后
@Override
public void theLast() {
System.out.println("关注个人公众号:Java3y");
}
@Override
protected void actualContent() {
System.out.println("你们好,我是3y,今天来给你们分享我写的模板方法模式");
}
}
复制代码
一样地,3y女友的文章模板也是相似的:
// 3y女友的文章模板
public class Java3yGFWriteArticle extends WriteArticle {
// 前言
@Override
public void introduction() {
System.out.println("balabalabalalabalablablalab");
}
// 最后
@Override
public void theLast() {
System.out.println("balabalabalalabalablablalab");
}
@Override
protected void actualContent() {
System.out.println("3y是傻子,不用管他");
}
}
复制代码
想要真正写文章的时候就十分方便了:
// 3y写文章
public static void main(String[] args) {
WriteArticle java3ywriteArticle = new Java3yWriteArticle();
java3ywriteArticle.writeAnCompleteArticle();
}
// 3y女友写文章
public static void main(String[] args) {
WriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();
java3yGFWriteArticle.writeAnCompleteArticle();
}
复制代码
要点:
嗯,上面的就是模板方法模式,就这么简单!
《设计模式之禅》:
定义一个操做中的算法框架,而将一些步骤延迟到子类中。使子类能够不改变一个算法的结构便可重定义该算法的某些步骤。
根据咱们上面的例子,来说讲这段话的含义:
好比3y在文章模板中的introduction()
改了,“只有充钱才能变强”
@Override
public void introduction() {
System.out.println("只有充钱才能变强");
}
复制代码
咱们没有碰过writeAnCompleteArticle()的代码,但再次调用这个方法的时候,具体的实现就会发生改变(由于writeAnCompleteArticle受子类的具体实现影响)
下面咱们看一下模板方法模式的通用类图:
在模板方法模式中,也有几个术语,根据咱们的例子中的注释,我给你们介绍一下:
// 抽象模板类
public abstract class WriteArticle {
// 基本方法
protected abstract void introduction();
// 基本方法
protected abstract void theLast();
// 基本方法
protected abstract void actualContent();
// 模板方法
public final void writeAnCompleteArticle() {
introduction();
actualContent();
theLast();
}
}
// 具体模板类
public class Java3yWriteArticle extends WriteArticle {
// 实现基本方法
@Override
public void introduction() {
System.out.println("只有充钱才能变强");
}
// 实现基本方法
@Override
public void theLast() {
System.out.println("关注个人公众号:Java3y");
}
// 实现基本方法
@Override
protected void actualContent() {
System.out.println("你们好,我是3y,今天来给你们分享我写的模板方法模式");
}
}
复制代码
优势:
缺点:
最经典的就是JUC包下的AQS(AbstractQueuedSynchronizer)了。AQS是什么?
AQS其实就是一个能够给咱们实现锁的框架。内部实现的关键是:先进先出的队列、state状态
咱们能够看一下AQS定义的acquire()
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
复制代码
acquire()
至关于模板方法,tryAcquire(arg)
至关于基本方法。
模板方法模式也很简单呀,一个抽象类有基本方法(等着被子类实现的方法),有模板方法(对外暴露、调用基本方法、定义了算法的框架),那就完事了。
推荐阅读和参考资料:
乐于分享和输出干货的Java技术公众号:Java3y。关注便可领取海量的视频资源!
精彩回顾:
以为个人文章写得不错,不妨点一下赞!