最近在开发的时候经常看到项目中大量使用模板设计模式和责任链设计模式,发现之前虽然了解但是使用较少,因此写本文学习一下。
模板方法
所谓的模板方式,其实很简单,比如去银行办理业务都需要经过区号,排队,办理业务,评价等一系列操作,但是每个人办理的业务都不一致,办理业务的流程就是一个模板,可是业务却不一致,这就是模板方法,主要用于将不变的行为抽象到父类中,去除子类的重复代码。以办理业务为例:定义的抽象模板如下:
/** * 银行业务流程模板 */ public abstract class BaseBusinessHandler { public void process(){ getNumber(); waitNum(); handle(); comment(); } protected void getNumber(){ System.out.println("getNumber"); } //区号 protected void waitNum(){ System.out.println("wait");} //等待 protected abstract void handle();//业务办理 protected void comment(){ System.out.println("comment");}//评价 }
存款业务办理,继承BaseBusinessHandler,实现存款的业务办理,其他方法继承父类,也可以重写;
public class SaveBusinessHandler extends BaseBusinessHandler { @Override protected void handle() { System.out.println("save"); } }
抢劫业务办理,也继承BaseBusinessHandler,实现抢劫业务:
public class RobBusinessHandler extends BaseBusinessHandler { @Override protected void handle() { System.out.println("rob"); } }
优点:
- 封装了不变的部分,如区号,排队,评价,把不变的部分交由父类实现,而把可变的部分交由子类实现,如业务办理;在父类中提取了公共方法,便于代码复用
- 可变部分由子类实现,子类可扩展实现相应功能
但是随着子类的增多,导致类个数大量增加;适用的场景是整体步骤是固定的,其中部分是可变的,将可变的部分抽象出来,供子类实现
责任链模式
定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。类似击鼓传花,和spring的interceptor拦截器。
比如一条消息,在发送的时候,需要判断消息的接受方是否在线,消息中是否含有敏感词等逻辑,使用责任链模式,每个处理逻辑只负责自己的业务部分即可,用户只需要将消息发送给责任链即可,无须关系具体的处理。因此,将消息的发送者和消息的处理者解耦了,降低了系统的耦合度,而且可以在责任链中添加新的处理逻辑,增强了系统的可扩展性;而且可以跳动处理的顺序从而改变工作的流程。但是不保证每个请求都被处理,由于没有明确的处理者,所以可能导致请求不一定会被处理,以消息发送为例,如果用户是超级VIP,可能不需要进行敏感词判断及脱敏,那敏感词判断的逻辑就不会进行处理,而且随着链路的增长,系统的性能可能受到影响。
先定义一个抽象的处理者:可以是抽象类或者是接口
public interface BaseInterceptor { boolean needHandle(); //判断是否需要处理 ErrorCode handle();//业务的处理 }
敏感词业务处理
public class SensitiveInterceptor implements BaseInterceptor { @Override public boolean needHandle() { return true; } @Override public ErrorCode handle() { if(!needHandle()) return null;//判断是否需要处理 System.out.println("sensitive"); return null; } }
接受方有效性校验
public class ReceiverInvalidInterceptor implements BaseInterceptor { @Override public boolean needHandle() { return true; } @Override public ErrorCode handle() { if(!needHandle()) return null; //判断是否需要处理 System.out.println("receiver valid"); return null; } }
任务链的生成及运行
List<BaseInterceptor> interceptors = new ArrayList<>(); interceptors.add(new SensitiveInterceptor()); interceptors.add(new ReceiverInvalidInterceptor()); for (BaseInterceptor item : interceptors) { ErrorCode error = item.handle(); // 根据任务链中每个处理逻辑返回值判断是否继续进行任务链的下一个逻辑处理 if (null != error) return; }
使用的场景:
- 有多个对象处理请求,哪个对象处理该请求在运行的时候判断
- 看动态调整处理顺序或者添加删除新的处理逻辑
- 在不指定处理者的时候,向多个处理者提交一个请求