Java设计模式——模板设计模式

655 阅读2分钟

模板设计模式

1.模板模式简介

模板模式(Template ):模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

2.模板模式的结构

模式中的角色:

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

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

406.png

3.通用代码如下

抽象模板类:

 public abstract class AbstractClass {
      //基本方法
      protected abstract void doSomething();
      //基本方法
      protected abstract void doAnything();
      //模板方法
      public void templateMethod(){
              /*
 ​
 调用基本方法,完成相关的逻辑
 ​
             this.doAnything();
             this.doSomething();
     }
 }

具体模板类:

 public class ConcreteClass1 extends AbstractClass {
      //实现基本方法
      protected void doAnything() {
              //业务逻辑处理
      }
      protected void doSomething() {
              //业务逻辑处理
      }
 }
 public class ConcreteClass2 extends AbstractClass {     //实现基本方法
      protected void doAnything() {
              //业务逻辑处理
      }
      protected void doSomething() {
              //业务逻辑处理
      }
 }

场景类:

 public class Client {
      public static void main(String[] args) {
              AbstractClass class1 = new ConcreteClass1();
              AbstractClass class2 = new ConcreteClass2();               
              //调用模板方法
              class1.templateMethod();
              class2.templateMethod();
      }

4.案例讲解

需求

  • 有多个类,完成不同的job
  • 要求能够得到各自的完成时间

1.)传统方式实现

代码

 package Abstract;
 ​
 public class AbstractExercise {
     public static void main(String[] args) {
         AA aa = new AA();
         aa.calcTime();
 ​
         BB bb = new BB();
         bb.calcTime();
     }
 }
 class AA {
     // 计算任务1
     // 1 + 2 + ...+ 100000
     public void calcTime() {
         //得到开始时间
         long start = System.currentTimeMillis();
         job(); // 计算执行任务的时间
         // 得到结束时间
         long end = System.currentTimeMillis();
         System.out.println("AA 执行的时间 " + (end - start) + "毫秒");
     }
 ​
     long sum = 0;
     public void job(){
         for (int i = 1; i <= 100000; i++) {
             sum += i;
         }
     }
 }
 ​
 class BB {
     // 计算任务2
     // 1*1 + 2*2 +... 10000*10000
     public void calcTime() {
         //得到开始时间
         long start = System.currentTimeMillis();
         job(); // 计算执行任务的时间
         // 得到结束时间
         long end = System.currentTimeMillis();
         System.out.println("BB 执行的时间 " + (end - start) + "毫秒");
     }
     long sum = 0;
     public void job(){
         for (int i = 1; i <= 10000; i++) {
             sum += i * i;
         }
     }
 }
 // CC类 DD类.......

对于不同的任务它们有自己各自的执行方式,我们需要做的是统计它们各自执行完任务所花费的时间。我们通过观察发现计算时间的方法被重复的使用,方法是一样的方法只是各个任务执行的细节不同罢了,如果有CC类 、DD类.......的不同任务job()——因此我们可以将其设置为抽象方法!,那么计算时间的方法calcTime()要在每一个类中使用!这样代码就大量的重复了,不利于修改与维护!——因此我们可以将其设置为模板方法!

2.)模板设计模式实现

抽象模板类(AbstractClass)

 package Abstract;
 ​
 public abstract class Tempalte { //父类——模板类
     public abstract void job();// 抽象方法
     
     // 模板方法
     public void calcTime() { // 实现方法,调用job()方法
         //得到开始时间
         long start = System.currentTimeMillis();
         job(); // 计算执行任务的时间————动态绑定机制
         // 得到结束时间
         long end = System.currentTimeMillis();
         System.out.println("任务执行的时间 " + (end - start) + "毫秒");
     }
 }
 ​

具体模板类(ConcreteClass)

 package Abstract;
 ​
 public class AA extends Tempalte{
     // 计算任务1
     // 1 + 2 + ...+ 100000
     long sum = 0;
     @Override
     public void job(){
         for (int i = 1; i <= 100000; i++) {
             sum += i;
         }
     }
 }
 ​
 package Abstract;
 ​
 public class BB extends Tempalte{
     // 计算任务2
     // 1*1 + 2*2 +... 10000*10000
     long sum = 0;
     @Override
     public void job(){
         for (int i = 1; i <= 10000; i++) {
             sum += i * i;
         }
     }
 }
 ​

测试类(ConcreteClass)

 package Abstract;
 ​
 public class Application {
     public static void main(String[] args) {
         Tempalte aa = new AA();
         aa.calcTime(); // 动态绑定机制,对多态的理解
         Tempalte bb = new BB();
         bb.calcTime();
     }
 }
 ​

5.模式模式优缺点:

1.)优点

模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

2.)缺点

每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。

3.)适用场景

在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守算法规则。

注:如果文章有任何错误或不足,请各位大佬尽情指出,评论留言留下您宝贵的建议!如果这篇文章对你有些许帮助,希望可爱亲切的您点个赞推荐一手,非常感谢啦

67.png