行为模式的包,然后创建一个templatemethod模板方法这样的一个包,这里面我们引入一个业务场景,例如说制作课程,这么一个业务场景,我现在在制作这个视频课程,那对于后端的JAVA课程,还有设计模式这个课程,在制作的时候,要制作PPT,制作视频,还要决定去写一个手记,还要提供前端的一些素材,例如前端的很多课程呢,都是要提供前端等素材的,而我们这个设计模式,又不提供图片素材,那不同的课程,制作的步骤主线上是一样的,但是在细分的一些细节上,还是有所不同,我们这个设计模式,一些图片的素材,我们是不需要提供的,而且本身我们也没有,那么是否去写手记,这个呢还不一定,有的课程制作的时候必须有配套的手记,那有一些并不是必须的,写手记并不是非必选项,完全留给子类来扩展,那么我们把这个方法做成钩子方法,那具体怎么实现呢,现在就让我们一起来coding,很简单,这个设计模式非常非常简单,首先我们创建一个类,这个类是什么呢,抽象类ACourse

这个设计模式学起来也是比较轻松的,就是一个单纯的抽象类,然后下边实现了抽象方法,Test我们先不看,我们主要看上边,右侧有一个needWriteArticle,这个方法正是重写父类的needWriteArticle,其他的没有变化,那我们再看一下前端课程这个类,我们要再演进一版,什么业务场景呢,FECourse,这个呢是一个前端课程,它是一个泛指,例如说,React,Vue,这些都是FECourse,对于后端课程来说,这个是一个具体的设计模式课程,当然我们没有起后端课程这么一个类,所以我们现在聚焦在FECourse,Vue需要写手记,而React不需要写手记,但是我们的这个类声明的是FECourse,那如果我们这么写,我们看一下

不要关注Test,还是看上边,模板方法的UML,清晰明了,非常容易理解,所以呢总结来说,对于我们这个模板方法设计模式,这个ACourse,也就是这个抽象类,就是一个模板,定义了一套标准,他呢是一种行为模式,把这些makePPT,makeVideo,这种固定的写法,这些步骤,以及这些顺序呢,都固定好,对于需要钩子方法的这些选择性方法,开放出去,而子类对于writeArticle实现是没有疑义的,而对于packageCourse,完全交给子类来实现,这里面要注意一下这个final,一定要加final,否则子类是可以重写makeCourse,也就是把步骤全部打乱,都OK的,模板方法就是为了定义一个模板,不想其他类把流程步骤给打乱,那模板方法这个模式的coding呢,就到这里,相信你们,设计模式肯定能学会,而且肯定能理解好
package com.learn.design.pattern.behavioral.templatemethod;/*** 它是一个抽象类* * * @author Leon.Sun**/
public abstract class ACourse {/*** 首先这里要写一个protected的方法* 这个权限控制* 这个方法声明成final的* 因为在ACourse里面定义的模板* 是不想被修改的* 所以这个方法声明成final的* 我们都用void makeCourse* 制作课程* 这里面注意* 声明final是不希望子类可以覆盖这个方法* 防止修改我们这个制作课程流程的执行顺序* 那这个方法先放到这儿* 现在我们来拆解一下这个小步骤* 首先我们要做一个PPT* 没什么说的* 所有的课程都要制作PPT* 无论现在网络上是免费的课程* 还是收费的课程* * 这里面要怎么写呢* 首先我们这个类是为了定义一个模板* 那这个模板关键方法是makeCourse* 首先我们调用一下makePPT* 必须要制作PPT* 然后要makeVideo* 就是必须要makeVideo* 那对于是否写手记来配套这个课程* 是可选的* 我们交由钩子方法来实现* 比如这里有一个needWriteArticle方法* 如果这个方法返回true的话* 我们调用writeArticle* 那这里就使用了模板方法里面的钩子方法* 最后我们再调用一下packageCourse* 那这里面刚刚也说了* 对于makePPT makeVideo writeArticle这里面的实现* 对于所有子类是没有疑义的* 所以我们声明为final的* * * */protected final void makeCourse(){this.makePPT();this.makeVideo();if(needWriteArticle()){this.writeArticle();}this.packageCourse();}/*** 直接制作PPT* 你们想一下void makePPT* 这个方法是不是也要是final的呢* 如果这个方法所有的子类都不需要重写的话* 那我们就要把它声明成final的* 也就是说这个行为是固定不变的* 制作什么课程* 都要制作PPT* 并且这里面的实现* 是满足所有子类的* * */final void makePPT(){System.out.println("制作PPT");}/*** 同理制作视频* 那我们这里的制作都用make这个动词了* 那我们再想象一下* * */final void makeVideo(){System.out.println("制作视频");}/*** 编写手记* 编写手记他是固定的* 就是编写手记* 玩不出来什么花样* 所以对于编写手记这个实现* 所有的子类是认可的* 但是小明要编写手记* 小刚就不编写手记了* 也就是说对于这个课程来说* 编写手记是一个可选项* 但是对于这里的实现* 子类都是认可的* 所以写手记这个方法* 我们也把他声明成final的* 所以我们声明一个钩子方法* * */final void writeArticle(){System.out.println("编写手记");}//钩子方法/*** 返回值是布尔* 是否需要编写手记* 默认return false* 并且他不是final的* 子类可以覆盖他* 写完钩子方法之后我们要写一个钩子方法* * * @return*/protected boolean needWriteArticle(){return false;}/*** 包装课程* 那对于设计模式这个包装来说呢* 我们要把项目的源码* 放到这个素材里面* 而对于一些前端的课程呢* 也要放源码* 他们还要放一些图片的素材* 也就是对于不同的课程* 包装课程* 上线之前* 提供的素材呢* 都是不一样的* 而把这个方法* 完全交给子类来实现* 所以对于使用模板方法这个设计模式的时候* 我们对于业务的一个模型* 一定要抽象化* 对于扩展性以及业务后续的发展* 哪些行为是固定的* 哪些行为是要交给子类的* 哪些行为是可选的* 这些都要把这个业务分析透* 然后再来设计这个模板方法* 设计模式的使用场景* 那现在我们来声明具体的子类实现课程* 例如DesignPatternCourse* * */abstract void packageCourse();
}
package com.learn.design.pattern.behavioral.templatemethod;/*** 我们让他继承ACourse* 实现里面的具体方法* 现在抽象方法只有一个* * * @author Leon.Sun**/
public class DesignPatternCourse extends ACourse {/*** 打包我们写一下具体的实现* 提供课程的JAVA源代码* 因为现在设计的业务场景* 已经覆盖了模板方法的业务场景* 所以对于设计模式这个课程来说* 在包装课程的时候* 我们需要提供JAVA源代码* 我们再写一个SECourse* 前端课程* * 可以来到这里试一下* 我们发现makePPT makeVideo makeArticle并不能重写* 这正是final的一个作用* 那我们现在回到测试函数里边* * */@Overridevoid packageCourse() {System.out.println("提供课程Java源代码");}@Overrideprotected boolean needWriteArticle() {return true;}}
package com.learn.design.pattern.behavioral.templatemethod;/*** 让他继承ACourse* 这里面也很简单* * * @author Leon.Sun**/
public class FECourse extends ACourse {/*** 默认是false* * */private boolean needWriteArticleFlag = false;/*** 首先提供课程的前端代码* 然后呢还要提供一个* 提供课程的图片等多媒体素材* 视频等等之类的* 视频嵌入到前端页面里* 使用的多媒体素材* 那我们现在来看一下* 他的UML图* * */@Overridevoid packageCourse() {System.out.println("提供课程的前端代码");System.out.println("提供课程的图片等多媒体素材");}/*** 现在我们使用构造器的方式* 那么我们再来到Test里边* * * @param needWriteArticleFlag*/public FECourse(boolean needWriteArticleFlag) {this.needWriteArticleFlag = needWriteArticleFlag;}/*** 代表所有的前端类都要写手记* 这个又不符合业务扩展的一个方向了* 那怎么办呢* 很简单* 把我们现在的模板方法模式呢* 再演进一步* 我们把needWriteArticle* 再开放给Test应用层* 怎么开放呢* 也是非常容易的* * 然后我们再重写这个方法* 返回值是什么呢* 就是this.needWriteArticleFlag* 然后我们通过构造器和setter的方式呢* 把needWriteArticleFlag开放给应用层* * * */@Overrideprotected boolean needWriteArticle() {return this.needWriteArticleFlag;}
}
package com.learn.design.pattern.behavioral.templatemethod;/*** 直接run一下* 看一下结果* 首先对于后端设计模式开始了* 制作PPT* 制作视频* 提供课程的JAVA源代码* end* 前端课程我们看一下* 制作PPT* 制作视频* 提供课程的前端代码* 提供课程的图片多媒体素材* 前端课程end* 那现在我们就要考虑一下* writeArticle写手记这么一个方法* 上线是有编写课程手记* 所以就想重写这个方法* needWriteArticle* return什么呢* return true* * * @author Leon.Sun**/
public class Test {public static void main(String[] args) {/*** 首先我们输出一个后端设计模式课程start* * */
//        System.out.println("后端设计模式课程start---");/*** 直接new一个DesignPatternCourse* 通过父类声明一个引用来指向子类的一个实例* * 因为Test里面new的是一个子类对象* 所以只要我们在这个类里面重写的话* 那对于模板里面要执行方法的时候* 拿到的就是子类的这个方法的返回值* 那对于现在这个设计模式的这个课程* 他会编写手记* 因为needWriteArticle默认的是返回false* 那我们再run一下* 可以看到后端课程设计的时候* 有一个编写手记* 但是前端并没有* 这个呢和预期一样* 因为前端并没有编写手记的方法* 而是选用了模板默认返回值false* 那这个就是钩子方法的具体使用* 非常简单* 我们看一下UML有什么变化呢* * */
//        ACourse designPatternCourse = new DesignPatternCourse();/*** 直接调用它的makeCourse()* 制作课程* * */
//        designPatternCourse.makeCourse();/*** 然后写一个end* * */
//        System.out.println("后端设计模式课程end---");System.out.println("前端课程start---");/*** 写一个前端的课程* * 现在我们想让我们的前端课程写手记* 赋值一个true* 上边我们先注释上* run一下* 编写手记了* 我们再把它改成false* 再run一下* 制作课程下边并没有编写手记* 那这里面想说明什么呢* 我特意设计这个case* 就想说对于模板方法* 抽象的层次* 例如说* 设计模式这个课程* 那在我们这个业务场景中* 我们把它定义为后端的一个课程* 其中的一个子课程* 而FECourse是一个大范围的课程* 例如说React* JavaScript* 或者呢* Vue这些* 都是前端课程* 如果我们没业务类型转化不够合理的话* 就会发生刚刚我写的这个case* 他两可以理解在我们这个业务场景中* 并不是同一个level的* 也就是设计模式的上一级* 所以这种情况* 我们有可能把适当的权限开放给应用层* 所以刚刚通过这种方式* 声明一个自己的变量* 然后通过构造器或者setter的方式呢* 把这个flag开放给应用层* 那这种使用方式* 还是要看具体的应用场景* 现在的这种写法是为了满足不同的FECourse* 对于手记可能有不同需求的* 实现满足方案* 那我们再看一下UML* * * */ACourse feCourse = new FECourse(false);feCourse.makeCourse();/*** 前端课程end* * */System.out.println("前端课程end---");}}

模板方法模式coding相关推荐

  1. 学妹惊呼:使用Java8改造后的模板方法模式真的是yyds

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 371 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 我们在日常开发中,经 ...

  2. Python设计模式(四) -- 模板方法模式

    模板方法模式 定义 定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤 适用场景: 事务处理的步骤具有共性,只是具体实施,根据 ...

  3. Java设计模式之模板方法模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  4. 设计模式--04模板方法模式

    文章目录 模板方法模式 定义 优点 缺点 使用场景 Python实现 模板方法模式 定义 定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结果即可重定义该算法的某些特 ...

  5. 设计模式之模板方法模式(Template Method)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. android 模板方法模式,安卓设计模式(七)模板方法模式

    模板方法模式用于固定相关操作的执行流程,将具体实现延迟到子类中 该系列其他文章: 定义: 定义一个操作中算法的框架,而降一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定 ...

  7. JAVA 设计模式 模板方法模式

    定义 模板方法模式 (Template Method) 定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模 ...

  8. 模板方法模式与策略模式的区别

    2019独角兽企业重金招聘Python工程师标准>>> 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义 ...

  9. 设计模式--模板方法模式

    2019独角兽企业重金招聘Python工程师标准>>> 模板方法模式(template method): 一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实 ...

最新文章

  1. 化工学python_化工计算与软件应用(第2版) PDF
  2. VISTA IIS Worker Process 已停止工作 解决办法
  3. python中@staticmethod、@classmethod和实例方法
  4. ALV显示红绿灯(FMnbsp;ALVnbsp;和nbsp;OOnbsp;ALV两…
  5. 模型融合(stackingblending)
  6. php5的程序如何安装在php7,centos安装php5和php7,并在apache里同时使用
  7. MIDL2011报错。
  8. codeblocks下载安装与解决codeblocks找不到编译器的方法
  9. html5均线图源码,通达信相当好的天机均线主图源码
  10. 【RPC Dubbo】本地存根和本地伪装
  11. Kent Beck:敏捷和极限编程是关于Be Yourself
  12. 线性代数笔记【空间向量】
  13. 【Prometheus】prometheus告警配置
  14. 磁盘无损简单卷转主分区
  15. js/jquery(2)
  16. 2021-05-26
  17. 算力网络 — 算力中心
  18. box-shadow和颜色渐变
  19. 「镁客早报」美国国会议员表示不会在今年通过无人车驾驶法案;苹果证实今年出货的iPad Pro有轻微弯曲...
  20. C8051F340 USB0 寄存器访问

热门文章

  1. 当excel 导入数据库的字段大于255时,把第一行的字段加长超过255.
  2. modbus-rtu qt4-serialport1------ xp as host
  3. 诗歌rails之 Logger
  4. 自定义类型处理器的应用
  5. 【JFreeChart】JFreeChart—输出时序图
  6. 19.并发容器之BlockingQueue
  7. Vue.js学习笔记四
  8. Linux 中识别 USB 设备名字的 4 种方法
  9. WKQ学习(后台知识)
  10. mac下android环境搭建笔记(android studio)