设计模式篇-模板方法设计模式

发布于 2021-10-10 23:43

什么是模板方法设计模式

首先看下什么叫模板:

模板是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化。

所以模板方法模式,简言之就是,在一个方法中定义一个算法骨架(业务逻辑的步骤),并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。

让我们来看下一个简单的例子:

首先我们定义一个模版类,以一个简单的电商支付场景举例。

public abstract class AbstractClass {    //这里定义了一个业务逻辑的步骤    //比如说简单的电商支付场景    //步骤1:进行扣减库存    //步骤2: 选择相应的支付方式    //步骤3: 通知买家下单成功    public final void templateMethod() {        //步骤1        method1();        //步骤2        method2();        //步骤3        method3();    }    private final void method1() {        System.out.println("扣减库存成功");    }    private final void method3() {        System.out.println("通知买家下单成功");    }    protected abstract void method2();}

这边实现了支付宝支付的情况:

public class ConcreteClass1 extends AbstractClass {    @Override    protected void method2() {        System.out.println("选择支付宝支付");    }}

这边实现了微信支付的情况:

public class ConcreteClass2 extends AbstractClass {    @Override    protected void method2() {        System.out.println("选择微信支付");    }}

模板方法设计模式的作用

模板模式作用一:复用

模板模式把一个算法中不变的流程抽象到父类的模板方法 templateMethod() 中,将可变的部分 method2() 留给子类 ContreteClass1 和 ContreteClass2 来实现。所有的子类都可以复用父类中模板方法定义的流程代码,相同的公共逻辑也可以在子类中复用。

模板模式作用二:扩展

通过模板模式提供功能扩展点,让用户可以在不修改框架源码的情况下,基于扩展点定制化功能。

模板方法设计模式的缺点

假设一个框架中的某个类暴露了两个模板方法,并且定义了一堆供模板方法调用的抽象方法,代码示例如下所示。在项目开发中,即便我们只用到这个类的其中一个模板方法,我们还是要在子类中把所有的抽象方法都实现一遍,这相当于无效劳动了。

public abstract class AbstractClass {  public final void templateMethod1() {    //...    method1();    //...    method2();    //...  }    public final void templateMethod2() {    //...    method3();    //...    method4();    //...  }    protected abstract void method1();  protected abstract void method2();  protected abstract void method3();  protected abstract void method4();}

那有没有想对应的解决方法呢?

其实我们可以用回调的方法,在需要用到的模板方法中注入回调对象即可。代码示例如下所示:

首先定义一个回调接口:

public interface ICallback {    void methodToCallback();}

相对应的模版类:

public abstract class AbstractClass {    public final void templateMethod1(ICallback callback) {        callback.methodToCallback();    }    public final void templateMethod2(ICallback callback) {        callback.methodToCallback();    }}

相对应的回调类:

public class ConcreteCallback1 implements ICallback{    @Override    public void methodToCallback() {        method1();        method2();    }    public void method1(){}    public void method2(){}}public class ConcreteCallback2 implements ICallback{    @Override    public void methodToCallback() {        method3();        method4();    }    public void method3(){}    public void method4(){}}

测试方法:

public static void main(String[] args) {        AbstractClass demo = new ConcreteClass1();        demo.templateMethod();    }

这样就解决了子类不需要重写所有模版类的抽象方法的问题。

本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。

相关素材