设计模式之模板模式

代码复用

  • 概念
  • 好处和使用场景
  • 类图
  • 代码实例

概念

在各个子类中包含了很多相同的逻辑,而且这个逻辑在各个子类中并不会改变,因此把这些不变的行为搬到一个抽象类中,去除了子类中的重复代码。但是会有几个步骤随不同子类会有不同,这个时候就需要在抽象类提供几个抽象方法由子类提供不同实现。

好处和使用场景

模板模式提供了一个很好的代码复用平台,使用场景:就是当我们从整体流程由一系列步骤组成,但是有几个步骤实现可能不同,这个时候应该要考虑使用模板模式。

类图

在这里插入图片描述

代码实例


NoneTemplate 没有使用模板模式的例子

/**
 * @author duanyimiao
 * @create 2018-07-27 11:14 AM
 * @description 看看如果不用模板模式情况
 **/
public class NoneTemplate {
    public void test(){
        /**
         * 从下面可以看到类r1和r2中又很多相同的代码
         * try{
         *  //可变的逻辑
         * }catch(Exception e){
         * //可变的逻辑
         * }finally{
         * //可变的逻辑
         * }
         * 因此把这些不变的放在抽象类中,然后可变的逻辑地方提供出三个抽象方法供不同子类进行实现,其中这些子类都实现了Runnable接口,所以抽象类也要实现该接口。具体可以看AbstractRunable 和RequestExecutor的实现
         *
         */
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                try{
                    //可能会抛出异常
                    System.out.println("run r1 logic");
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("run r1 logic when it throw exception ");
                }finally {
                    System.out.println("run r1 logic finally execute");
                }
            }
        };

        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                try{
                    //可能会抛出异常
                    System.out.println("run r2 logic");
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("run r2 logic when it throw exception ");
                }finally {
                    System.out.println("run r2 logic finally execute");
                }
            }
        };
    }
}

AbstractRunnable 抽象模板类

/**
 * @author duanyimiao
 * @create 2018-07-27 10:52 AM
 * @description 模版模式
 * 提供了实现Runnable的抽象方法,并且提供了抽象方法给子类进行实现,一些公共逻辑在抽象类实现
 **/
public abstract class AbstractRunnable implements Runnable {
    @Override
    public void run() {
        try {
            doRun();
        } catch (Exception e) {
            onFailure(e);
        } finally {
            onAfter();
        }
    }

    //由子类进行实现具体的动作
    public abstract void doRun();

    //子类进行实现该方法,对失败做逻辑处理
    public abstract void onFailure(Exception e);

    //当超过线程池处理能力时执行的方法,该方法最终由线程池逻辑中调用的
    public void onReject(Exception e) {
        onFailure(e);
    }

    //在正常执行或异常 最终都会调用 空实现
    public void onAfter() {

    }
}

RequestExecutor 具体的实现抽象类的抽象方法的类

/**
 * @author duanyimiao
 * @create 2018-07-27 11:14 AM
 * @description 线程池进行处理,调用doRun执行逻辑,当操作执行异常会调用onFailure,如果超过了线程池承受范围则会执行onReject方法
 **/
public class RequestExecutor extends AbstractRunnable {

    @Override
    public void doRun() {
        System.out.println("execute request logic");
        throw new RuntimeException("error");
    }

    @Override
    public void onFailure(Exception e) {
        System.out.println("execute request error" + e);
    }

    @Override
    public void onAfter() {
        System.out.println("execute request ultimately");
    }
}

Client 测试类,如果想要使用多线程完成不同的业务逻辑,只需要继承AbstractRunnable类就行,然后实现抽象方法,无需关注什么时候抛出异常,以及这些方法调用顺序都不需要care,只需要完成对应方法的逻辑就行

/**
 * @author duanyimiao
 * @create 2018-09-23 10:35 PM
 * @description
 **/
public class Client {
    public static void main(String[] args) {
        Thread thread = new Thread(new RequestExecutor());
        thread.start();
    }
}

输出结果

execute request logic
execute request errorjava.lang.RuntimeException: error
execute request ultimately
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值