代码复用
- 概念
- 好处和使用场景
- 类图
- 代码实例
概念
在各个子类中包含了很多相同的逻辑,而且这个逻辑在各个子类中并不会改变,因此把这些不变的行为搬到一个抽象类中,去除了子类中的重复代码。但是会有几个步骤随不同子类会有不同,这个时候就需要在抽象类提供几个抽象方法由子类提供不同实现。
好处和使用场景
模板模式提供了一个很好的代码复用平台,使用场景:就是当我们从整体流程由一系列步骤组成,但是有几个步骤实现可能不同,这个时候应该要考虑使用模板模式。
类图
代码实例
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