一分钟学会《模板方法模式》 (2)

想要真正写文章的时候就十分方便了:

// 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(); }

要点:

把公共的代码抽取出来,如果该功能是不确定的,那我们将其修饰成抽象方法。

将几个固定步骤的功能封装到一个方法中,对外暴露这个方法,就可以非常方便调用了。

嗯,上面的就是模板方法模式,就这么简单!

1.3模板方法模式介绍

《设计模式之禅》:

定义一个操作中的算法框架,而将一些步骤延迟到子类中。使子类可以不改变一个算法的结构即可重定义该算法的某些步骤。

根据我们上面的例子,来讲讲这段话的含义:

定义一个操作中的算法框架,而将一些步骤延迟到子类中。

WriteArticle中有一个writeAnCompleteArticle()方法,该方法定义了发文章的所有步骤,但是这些步骤大多是抽象的,得由子类来实现。

使子类可以不改变一个算法的结构即可重定义该算法的某些步骤

外界是通过调用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,今天来给大家分享我写的模板方法模式"); } }

基本方法:在子类实现,并且在模板方法中被调用

模板方法:定义了一个框架,实现对基本方法的调用,完成固定的逻辑

1.4模板方法的优缺点

优点:

封装不变的部分,扩展可变的部分。把认为是不变的部分的算法封装到父类,可变部分的交由子类来实现!

提取公共部分的代码,行为由父类控制,子类实现!

缺点:

抽象类定义了部分抽象方法,这些抽象的方法由子类来实现,子类执行的结果影响了父类的结果(子类对父类产生了影响),会带来阅读代码的难度!

1.5模板方法模式JDK应用

最经典的就是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)相当于基本方法。

tryAcquire方法被多个子类实现

最后

模板方法模式也很简单呀,一个抽象类有基本方法(等着被子类实现的方法),有模板方法(对外暴露、调用基本方法、定义了算法的框架),那就完事了。

推荐阅读和参考资料:

《设计模式之禅》

https://blog.csdn.net/carson_ho/article/details/54910518

https://blog.csdn.net/hguisu/article/details/7564039

乐于分享和输出干货的Java技术公众号:Java3y。关注即可领取海量的视频资源!

帅的人都关注了

精彩回顾:

觉得我的文章写得不错,不妨点一下

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzgzp.html