策略模式
策略模式解耦策略的定义、创建、使用
策略的定义:一个策略接口和实现这个接口的策略类
策略的创建:策略模式包括一组策略,通过type来判断创建哪种策略,策略工厂,使用HashMap存储type与具体策略的关系
策略类有状态与无状态
策略的使用:运行时动态确定,通过配置文件来设置使用哪种type创建策略
例子:根据文件大小选择不同排序方式、根据订单类型选择不同结算方式
观察者模式
定义:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依
赖的对象都会自动收到通知
被观察者:Observable(被依赖的对象)
观察者:Observer(依赖的对象)
Subject-Observer
Publisher-Subscriber
Producer-Consumer
EventEmitter-EventListener
Dispatcher-Listener
场景:
一个注册接口,用户注册成功给用户发放优惠券,如果注册和发放优惠券都写在注册接口,违反单一职责原则,
使用观察者模式,UserController作为被观察者,注册了若干个观察者,当注册成功后,依次调用注册在上面的观察者
类似事件监听器模式,EventSource EventListener Event(type)
模板方法模式
定义:模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类
中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些
步骤
复用:
InputStream用到模板方法模式,read()函数留给具体子类实现
AbstractList的addAll()方法,add()方法留给具体子类,本类直接抛出不支持异常
扩展:
这里所说的扩展,并不是指代码的扩展性,而是指框架的扩展性,有点类似我们之前讲到的控制反转
模板模式常用在框架的开发中,让框架用户可以在不修改框架源码的情况下,定制化框架的功能
Java Servlet HttpServlet#service()->UserServlet#doGet/doPost()
JUnit TestCase,测试类继承TestCase类,TestCase类的runBare()函数是模板方法,定义执行流程,
子类可以重写setUp()、runTest()、tearDown()方法
同步回调类似模板方法模式,JdbcTemplate
异步回调类似观察者模式,给按钮添加事件监听器,Runtime.getRuntime().addShutdownHook(new ShutdownHook())/hook
回调与模板方法模式的区别
1、代码实现上,回调基于组合关系,模板方法模式基于继承关系
桥接模式
桥接模式的定义是:将抽象与实现解耦,让它们可以独立开来
比如有一个场景:根据不同类型的紧急程度,将消息发送到不同渠道
不同类型的紧急程度分为:SEVERE(严重)、URGENCY(紧急)、NORMAL(普通)、TRIVIAL(无关紧要)
不同渠道分为:邮件、短信、微信、自动语音电话
通知类Notification有一个方法notify(NotificationEmergencyLevel level, String message)
,作用是根据不同类型的level发送消息到不同渠道,代码逻辑是根据level进行if else判断
上面的设计不利于扩展,可以将不同渠道的消息发送逻辑抽取出来,形成独立的消息发送类MsgSender,
Notification 类相当于抽象,MsgSender类相当于实现,两者可以独立开发,通过组合关系(也就是桥梁)任意组合在一起
public interface MsgSender {
void send(String message);
}
public class TelephoneMsgSender implements MsgSender{
@Override
public void send(String message) {
}
}
public abstract class Notification{
protected MsgSender msgSender;
public Notification(MsgSender msgSender){
this.msgSender=msgSender;
}
public abstract void notify(String message);
}
public class SevereNotification extends Notification{
public SevereNotification(MsgSender sender){
super(sender);
}
@Override
public void notify(String message) {
sender.send(message);
}
}
public static void main(String[] args){
Map<String,Notification> notifies=new HashMap<>();
Notification notification=notifies.get("SEVERE");
notification.notify("test");
}
适配器模式
适配器模式:用来做适配的,将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作
实现方式:类适配器 对象适配器
ITarget-要转化成的接口定义
Adaptee-一组不兼容 ITarget接口定义的接口
Adaptor-将 Adaptee 转化成一组符合 ITarget 接口定义的接口
如果Adaptee接口很多并且和ITarget接口定义大部分相同,使用类适配器,因为Adaptor实现ITarget接口,需要重写其所有方法
而父类Adaptee已经定义了方法的实现,子类Adaptor就不需要实现了,代码量要少
类适配器:继承关系
class Adaptor extends Adaptee implements ITarget
对象适配器:组合关系
class Adaptor implements ITarget{
Adaptee adaptee;
}
职责链模式
职责链模式:一条链上有多个处理器,一个请求先到第一个处理器,如果第一个处理器可以处理这个请求,那么就
处理它,如果不能就交给链上的下一个处理器,依次类推
变体:链上的处理器都处理一遍请求
例子:敏感词过滤,敏感词过滤器链包含一系列的敏感词过滤器,只要链上有一个过滤器返回false,就被判断它是敏感词
版本1:用链表存储当前处理器的下一个处理器
版本2:用链表存储当前处理器的下一个处理器,父类定义模板方法来调用下一个处理器,子类重写业务方法
版本3:用数组存储所有处理器,处理器包含一个接口和若干实现类,接口方法返回布尔值
职责链模式的实现包含处理器接口或抽象类以及处理器链,
对应到Servlet Filter,javax.servlet.Filter 就是处理器接口,FilterChain 就是处理器链
Tomcat对于FilterChain的实现是ApplicationFilterChain,采用递归实现处理器链,这样可以双向拦截
Spring Interceptor职责链模式的处理器接口是HandlerInterceptor,处理器链是HandlerExecutionChain