设计模式之“模板方法模式(TemplateMethod)”
一、使用场景
场景1
当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理
例如:将子类重复声明的方法提到父类去声明,利用多态性,实现了代码的复用(子类重写)
场景2
遇到由一系列步骤构成的过程需要执行,这个过程从高层次上看是相同的,但有些步骤的实现可能不通,这时候,我们通常就可以考虑使用模板方法模式了
二、定义
模板方法模式:定义一个操作中的算法的股价,而将一些步骤延迟到子类中。
模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
三、特点
通过把不变行为(固定的数据加载)搬移到超类,去除子类中的重复代码来体现他的优势(这里就算没有抽象行为,只要抽象方法也是可以的)。
他提供了一个很好的代码复用平台。
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,而我们需要吧不变的行为搬到单一的地方,这样就可以帮助子类摆脱重复的不变行为纠缠,而产生的重复代码
四、结构图
五、案例
AbstractClass
是抽象类,其实也就是“抽象模板” ,定义并实现了一个模板方法。
这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而且逻辑的组成步骤在相对应的抽象操作中,推迟到子类实现。
顶级逻辑也有可能调用一些具体方法(1.0项目中有用到,主要用于公共数据初始化)
package com.template.templateVersionTwo; /** * 抽象类 * * @author 王子威 * @date 2022/8/2 */ public abstract class AbstractClass { /** * 抽象行为 * 放到子类实现 */ public abstract void primitiveOperationOne(); /** * 抽象行为 * 放到子类实现 */ public abstract void primitiveOperationTwo(); /** * 模板方法 * 给出逻辑骨架 * 推迟子类实现 * 个人感觉:很像切面 */ public void templateMethod() { primitiveOperationOne(); primitiveOperationTwo(); System.out.println("wzw"); } }
ConcreteClass
实现父类所定义的一个或多个抽象方法
每个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不通实现,从而使得顶级逻辑的实现各不相同
ConcreteClassA
package com.template.templateVersionTwo; /** * 具体实现类 * * @author 王子威 * @date 2022/8/2 */ public class ConcreteClassA extends AbstractClass { @Override public void primitiveOperationOne() { System.out.println("具体A类方法1的实现"); } @Override public void primitiveOperationTwo() { System.out.println("具体A类方法2的实现"); } }
ConcreteClassB
package com.template.templateVersionTwo; /** * 具体实现类 * * @author 王子威 * @date 2022/8/2 */ public class ConcreteClassB extends AbstractClass { @Override public void primitiveOperationOne() { System.out.println("具体B类方法1的实现"); } @Override public void primitiveOperationTwo() { System.out.println("具体B类方法2的实现"); } }
TestTemplate
测试方法testVersionTwo
@Test public void testVersionTwo() { AbstractClass abstractClass; abstractClass = new ConcreteClassA(); abstractClass.templateMethod(); abstractClass = new ConcreteClassB(); abstractClass.templateMethod(); }
测试结果
* 博客文章部分截图及内容来自于学习的书本及相应培训课程,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。
* 备注:王子威
* 我的网易邮箱:wzw_1314_520@163.com