• Java设计模式之模板方法模式(Template Method)


    一、含义

      定义一个算法中的操作框架,而将一些步骤延迟到子类中。使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤,不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。

    二、模式中的角色

      抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。

      具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法

    三、类图及源码

    模板方法模式的通用类图非常简单,仅仅使用了Java的继承机制,但它是一个非常广泛的模式。其类图如下,其中AbstractClass叫做抽象模板,它的方法分为两类:

    • 基本方法:是由子类实现的方法,并且在模板方法被调用。(一般都加上final关键字,防止被覆写)
    • 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调用,完成固定的逻辑。(抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限)

                   

    上述通用类图的源码如下:

     1 public abstract class AbstractClass {
     2     protected abstract void doAnything();
     3     protected abstract void doSomething();
     4     public final void templateMethod(){
     5         /*
     6          * 调用基本方法,完成相关的逻辑
     7          */
     8         this.doAnything();
     9         this.doSomething();
    10     }
    11 }
    12 public class ConcreteClass1 extends AbstractClass {
    13 
    14     @Override
    15     protected void doAnything() {
    16         // TODO Auto-generated method stub
    17         //子类实现具体
    18     }
    19 
    20     @Override
    21     protected void doSomething() {
    22         // TODO Auto-generated method stub    
    23     }
    24 }
    25 public class ConcreteClass2 extends AbstractClass {
    26 
    27     @Override
    28     protected void doAnything() {
    29         // TODO Auto-generated method stub
    30         //子类实现具体
    31     }
    32 
    33     @Override
    34     protected void doSomething() {
    35         // TODO Auto-generated method stub    
    36     }
    37 }

    四、优缺点

    1、模板方法模式的优点

    • 封装不变部分,扩展可变部分。把认为不变部分的算法封装到父类中实现,而可变部分的则可以通过继承来继续扩展。
    • 提取公共部分代码,便于维护。
    • 行为由父类控制,子类实现。

    2、模板方法模式的缺点

      按照设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类负责完成具体的事务属性和方法,但是模板方式正好相反,子类执行的结果影响了父类的结果,会增加代码阅读的难度。

    五、使用场景

    • 多个子类有共有的方法,并且逻辑基本相同
    • 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
    • 重构时,模板方法是一个经常使用的方法,把相同的代码抽取到父类中,然后通过构造函数约束其行为

    六、实例

    以准备去学校所要做的工作(prepareGotoSchool)为例,假设需要分三步:穿衣服(dressUp),吃早饭(eatBreakfast),带上东西(takeThings)。学生和老师要做得具体事情肯定有所区别。

    抽象类AbstractClass

     1 public abstract class AbstractPerson{  
     2      //抽象类定义整个流程骨架  
     3      public void prepareGotoSchool(){  
     4           dressUp();  
     5           eatBreakfast();  
     6           takeThings();  
     7      }  
     8      //以下是不同子类根据自身特性完成的具体步骤  
     9      protected abstract void dressUp();  
    10      protected abstract void eatBreakfast();  
    11      protected abstract void takeThings();  
    12 }

    具体类ConcreteClass

     1     public class Student extends AbstractPerson{  
     2          @Override  
     3          protected void dressUp() {  
     4               System.out.println(“穿校服");  
     5          }  
     6          @Override  
     7          protected void eatBreakfast() {  
     8               System.out.println(“吃妈妈做好的早饭");  
     9          }  
    10       
    11          @Override  
    12          protected void takeThings() {  
    13               System.out.println(“背书包,带上家庭作业和红领巾");  
    14          }  
    15     }  
     1     public class Teacher extends AbstractPerson{  
     2          @Override  
     3          protected void dressUp() {  
     4               System.out.println(“穿工作服");  
     5          }  
     6          @Override  
     7          protected void eatBreakfast() {  
     8               System.out.println(“做早饭,照顾孩子吃早饭");  
     9          }  
    10       
    11          @Override  
    12          protected void takeThings() {  
    13               System.out.println(“带上昨晚准备的考卷");  
    14          }  
    15     }  

    测试类:

    1 public class Client {  
    2      public static void main(String[] args) {  
    3      Student student = new Student()  
    4      student.prepareGotoSchool();  
    5   
    6      Teacher teacher  = new Teacher()  
    7      teacher.prepareGotoSchool();  
    8      }  
    9 }
  • 相关阅读:
    poj_2506_Tiling_201407211555
    poj_2524_Ubiquitous Religions_201407211506
    poj_2586_Y2K Accounting Bug_201407211318
    poj_3006_Dirichlet's Theorem on Arithmetic Progressions_201407041030
    POJ训练计划
    nyoj_10_skiing_201405181748
    nyoj_308_Substring_201405091611
    nyoj_205_求余数_201404271630
    hdu_2082_找单词_201404271536
    nyoj_176_队花的烦恼二_201404262008
  • 原文地址:https://www.cnblogs.com/zq-boke/p/8514566.html
Copyright © 2020-2023  润新知