1、清晰的划分类或对象的行为或职责,定义他们之间的相互协作,完成复杂的功能
2、监听器模式、模板模式、策略模式、责任链模式、访问者模式、状态模式、备忘录模式、中介者模式、迭代器模式、命令模式、解释器模式
一、监听器 / 观察者模式
// 事件源-事件-监听器
eventSource-event-listener(handler)
eventSource.addListener
// 被观察者-消息-观察者
observable-message-obserber(handler)
observalbe.subscribe
/**
* 事件源和监听器是紧耦合的
* 事件源提供注入监听器的方法,使用前必须注入特定的监听器
* 事件源提供触发事件的方法,并在方法中调用监听器提供的回调函数
*/
public class Event {}
public class EventSource {
private EventListener listener;
public void setEventListener(EventListener listener) {
this.listener = listener;
}
public void happenEvent(Event e) {
listener.doEvent(e);
}
}
public class EventListener {
public void doEvent(Event e) {}
}
二、生产者消费者 / 发布订阅模式
生产者producer和消费者consumer是松散耦合的,两者之间无法感知对方的存在,需通过消息中间件关联
生产者:调用send方法发送带主题的消息到消息服务器
消息message:带有主题属性的信息
消息服务器broker:接收指定主题的消息入队,通知订阅该主题的消费者
主题topic:发布订阅方式,所有订阅该主题的消费者都会拿到消息来消费
队列queue:点对点方式,所有消费者都可从队列中取消息,但只能有一个消费者拿到消息并消费
消费者consumer:接收消息,并回调处理函数;有两种接受消息的方式:push推、pull拉
消息监听器/处理器MessageListener/Handler:确定topic,提供消息处理方法onMessage(List messages)
broker push
1、consumer启动后连接broker,告知broker它要订阅的topic
2、broker维护一个map,k-topic,v-订阅该topic的consumer列表
3、当主题队列中有消息时,borker从map中取出对应主题的消费者列表
异步发送消息给各个consumer,消费者拿到消息后执行消息处理函数,consumer需要有一个线程监听broker发送的消息
以rpc的方式异步调用各个consumer的消息处理函数
consumer pull
消费者需要编写pull函数,以轮询或者定时的方式从broker拉取消息,然后调用消息处理函数处理
可以按照自己的节奏控制消费,需要额外的cpu消耗
可能导致消费延迟,数据不一致,消息服务器消息积压
特点
1、解耦:无实际调用关系
反例:a、b系统交互,b需要调用a的api拿到数据再做处理
2、异步:减少同步阻塞,提高响应时间
反例:修改配置接口,需先入库然后同步缓存,导致入库后同步阻塞等待缓存完成,若缓存失败入库也要重试
3、存储:消息持久化,可以重试、找回、恢复、排查
4、扩展:增删业务方便,上游新增业务后,下游新增一个消息订阅即可,仅做扩展
5、过载保护:若上游产生了大量变更操作,下游按自己的节奏消费,起到缓冲