网站建设需要c语言吗,免费企业网站源码下载,网站首页不见怎么做,泰安房产网新楼盘一.观察者模式
观察者模式是一种行为型设计模式#xff0c;它定义了一种一对多的依赖关系#xff0c;当一个对象的状态发生改变时#xff0c;其所有依赖者都会收到通知并自动更新。当对象间存在一对多关系时#xff0c;则使用观察者模式#xff08;Observer Pattern…一.观察者模式
观察者模式是一种行为型设计模式它定义了一种一对多的依赖关系当一个对象的状态发生改变时其所有依赖者都会收到通知并自动更新。当对象间存在一对多关系时则使用观察者模式Observer Pattern。比如当一个对象被修改时则会自动通知依赖它的对象。观察者模式属于行为型模式。
意图定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。
主要解决一个对象状态改变给其他对象通知的问题而且要考虑到易用和低耦合保证高度的协作。
何时使用一个对象目标对象的状态发生改变所有的依赖对象观察者对象都将得到通知进行广播通知。
如何解决使用面向对象技术可以将这种依赖关系弱化。
关键代码在抽象类里有一个 ArrayList 存放观察者们。
应用实例 1、拍卖的时候拍卖师观察最高标价然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿菩萨洒了一地水招来一个老乌龟这个乌龟就是观察者他观察菩萨洒水这个动作。
优点 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点 1、如果一个被观察者对象有很多的直接和间接的观察者的话将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话观察目标会触发它们之间进行循环调用可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的而仅仅只是知道观察目标发生了变化。
使用场景
一个抽象模型有两个方面其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。一个对象的改变将导致其他一个或多个对象也发生改变而不知道具体有多少对象将发生改变可以降低对象之间的耦合度。一个对象必须通知其他对象而并不知道这些对象是谁。需要在系统中创建一个触发链A对象的行为将影响B对象B对象的行为将影响C对象……可以使用观察者模式创建一种链式触发机制。
注意事项 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行某一观察者错误会导致系统卡壳一般采用异步方式。
观察者模式包含以下几个核心角色
主题Subject也称为被观察者或可观察者它是具有状态的对象并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。观察者Observer观察者是接收主题通知的对象。观察者需要实现一个更新方法当收到主题的通知时调用该方法进行更新操作。具体主题Concrete Subject具体主题是主题的具体实现类。它维护着观察者列表并在状态发生改变时通知观察者。具体观察者Concrete Observer具体观察者是观察者的具体实现类。它实现了更新方法定义了在收到主题通知时需要执行的具体操作。
观察者模式通过将主题和观察者解耦实现了对象之间的松耦合。当主题的状态发生改变时所有依赖于它的观察者都会收到通知并进行相应的更新。
二.demo
1.事件监听接口
public interface EventListener {void doEvent(LotteryResult result);
}
2.实现监听接口短信、MQ
public class MessageEventListener implements EventListener {private Logger logger LoggerFactory.getLogger(MessageEventListener.class);Overridepublic void doEvent(LotteryResult result) {logger.info(给⽤户 {} 发送短信通知(短信){}, result.getuId(),result.getMsg());}
}
public class MQEventListener implements EventListener {private Logger logger LoggerFactory.getLogger(MQEventListener.class);Overridepublic void doEvent(LotteryResult result) {logger.info(记录⽤户 {} 摇号结果(MQ){}, result.getuId(),result.getMsg());}
}
3.事件管理类
public class EventManager {MapEnumEventType, ListEventListener listeners new HashMap();public EventManager(EnumEventType... operations) {for (EnumEventType operation : operations) {this.listeners.put(operation, new ArrayList());}}public enum EventType {MQ, Message}/*** 订阅** param eventType 事件类型* param listener 监听*/public void subscribe(EnumEventType eventType, EventListenerlistener) {ListEventListener users listeners.get(eventType);users.add(listener);}/*** 取消订阅** param eventType 事件类型* param listener 监听*/public void unsubscribe(EnumEventType eventType, EventListenerlistener) {ListEventListener users listeners.get(eventType);users.remove(listener);}/*** 通知** param eventType 事件类型* param result 结果*/public void notify(EnumEventType eventType, LotteryResult result) {ListEventListener users listeners.get(eventType);for (EventListener listener : users) {listener.doEvent(result);}}
}
整个处理的实现上提供了三个主要⽅法订阅( subscribe )、取消订阅( unsubscribe )、通知 ( notify )。这三个⽅法分别⽤于对监听时间的添加和使⽤。
另外因为事件有不同的类型这⾥使⽤了枚举的⽅式进⾏处理也⽅便让外部在规定下使⽤事件 ⽽不⾄于乱传信息( EventType.MQ 、 EventType.Message )。
4.业务抽象类接⼝
public abstract class LotteryService {private EventManager eventManager;public LotteryService() {eventManager new EventManager(EventManager.EventType.MQ,EventManager.EventType.Message);eventManager.subscribe(EventManager.EventType.MQ, newMQEventListener());eventManager.subscribe(EventManager.EventType.Message, newMessageEventListener());}public LotteryResult draw(String uId) {LotteryResult lotteryResult doDraw(uId);// 需要什么通知就给调⽤什么⽅法eventManager.notify(EventManager.EventType.MQ, lotteryResult);eventManager.notify(EventManager.EventType.Message,lotteryResult);return lotteryResult;}protected abstract LotteryResult doDraw(String uId);
}5.业务接⼝实现类
public class LotteryServiceImpl extends LotteryService {private MinibusTargetService minibusTargetService newMinibusTargetService();Overrideprotected LotteryResult doDraw(String uId) {// 摇号String lottery minibusTargetService.lottery(uId);// 结果return new LotteryResult(uId, lottery, new Date());}
}
6.测试
Test
public void test(){LotteryService lotteryServicenew LotteryServiceImpl();LotteryResult resultlotteryService.draw(2765789109876);logger.info(测试结果{},JSON.toJSONString(result));}
参考观察者模式 | 菜鸟教程
《重学Java设计模式》