常用设计模式杂谈

策略模式

策略模式解耦策略的定义、创建、使用

策略的定义:一个策略接口和实现这个接口的策略类

策略的创建:策略模式包括一组策略,通过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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值