java之观察者模式
一、Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。JDK里提供的observer设计模式的实现由java.util.Observable类和 java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。
二、观察者模式的优点:
2)Subject触发时:
五、这里写了一个实际开发中很有用的观察者模式的架构
1)观察者实现,抽象类的目的在于开发者只需要处理onMessage中的数据即可,不需要处理更多数据
package com.pinnet.observer; import com.pinnet.observable.MessageObservable; import javax.jms.ObjectMessage; import java.util.Observable; import java.util.Observer; /** * 观察者 * 抽象类的目的是更好的简化开发,实际开发中很有必要 */ public abstract class MessageObserver implements Observer { /** * 目的是在操作观察者的时候就加入到对应的被观察者中 * @param messageObservable */ public MessageObserver(MessageObservable messageObservable) { if (messageObservable == null) { return; } messageObservable.addObserver(this); } /** * 数据存在改变时触发,也是消息接收者 * @param observable * @param object */ public void update(Observable observable, Object object) { //这里采用ObjectMessage的数据形式,为了更好的传输对象数据 ObjectMessage objectMessage = (ObjectMessage) object; onMessage(objectMessage); } /** * 消息处理,需要具体实现 * @param objectMessage */ public abstract void onMessage(ObjectMessage objectMessage);
}
2)被观察者的继承,被观察者的方法基本都完善了,我们这里继承的目的是为了更好的理解
package com.pinnet.observable; import javax.jms.ObjectMessage; import java.util.Observable; /** * 被观察者 * 用来发送消息,这里不直接应用,采用消息中心模式在处理 */ public class MessageObservable extends Observable { /** * 发送消息在center中使用 * @param objectMessage */ public void sendMessage(ObjectMessage objectMessage) { //设置改变点 setChanged(); //发给观察者 notifyObservers(objectMessage); } }
3)消息处理中心,目的是为了提供更有用的工具
package com.pinnet.center; import com.pinnet.observable.MessageObservable; import org.apache.activemq.command.ActiveMQObjectMessage; import javax.jms.JMSException; import javax.jms.ObjectMessage; import java.io.Serializable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 消息处理中心,所有操作全部在这里 */ public class MessageCenter { //用于保存具体被观察者,发送数据,注册等 public static Map<MessageType, MessageObservable> messageMap = new ConcurrentHashMap<MessageType, MessageObservable>(); /** * 获取被观察者,添加观察者 * @param messageType * @return */ public MessageObservable getMessageObservable(MessageType messageType) { if (messageMap.containsKey(messageType)) { return messageMap.get(messageType); } else { MessageObservable messageObservable = new MessageObservable(); messageMap.put(messageType, messageObservable); return messageObservable; } } /** * 发送消息,统一入口 * @param messageType * @param serializable */ public void sendMessage(MessageType messageType, Serializable serializable) { if (messageMap.containsKey(messageType)) { try { MessageObservable messageObservable = messageMap.get(messageType); //这里采用的是ActiveMQ中实现类,当然可以自己实现ObjectMessage也可以 ObjectMessage objectMessage = new ActiveMQObjectMessage(); objectMessage.setObject(serializable); //被观察者发送给每个观察者 messageObservable.sendMessage(objectMessage); } catch (JMSException e) { e.printStackTrace(); } } } /** * 枚举类的目的是更好的控制数据发送 */ public enum MessageType { PUB,SUB } }
4)测试:简单实现一下即可,当然需要注册(注册部分可以写成xml,也可以自己写启动类)
a、写了两个观察者的实现类
package com.pinnet.observer.impl; import com.pinnet.observable.MessageObservable; import com.pinnet.observer.MessageObserver; import javax.jms.JMSException; import javax.jms.ObjectMessage; /** * 消息监听 */ public class PUBMessageListener extends MessageObserver { /** * 目的是在操作观察者的时候就加入到对应的被观察者中 * * @param messageObservable */ public PUBMessageListener(MessageObservable messageObservable) { super(messageObservable); } /** * 消息处理 * @param objectMessage */ public void onMessage(ObjectMessage objectMessage) { try { System.out.println(objectMessage.getObject()); } catch (JMSException e) { e.printStackTrace(); } } }
package com.pinnet.observer.impl; import com.pinnet.observable.MessageObservable; import com.pinnet.observer.MessageObserver; import javax.jms.JMSException; import javax.jms.ObjectMessage; public class SUBMessageListener extends MessageObserver { /** * 目的是在操作观察者的时候就加入到对应的被观察者中 * * @param messageObservable */ public SUBMessageListener(MessageObservable messageObservable) { super(messageObservable); } /** * 消息处理 * @param objectMessage */ public void onMessage(ObjectMessage objectMessage) { try { System.out.println(objectMessage.getObject()); } catch (JMSException e) { e.printStackTrace(); } } }
b、注册:统一写在了MessageCenter中
/** * 注册 */ public static void init() { new PUBMessageListener(MessageCenter.getMessageObservable(MessageType.PUB)); new PUBMessageListener(MessageCenter.getMessageObservable(MessageType.PUB)); new SUBMessageListener(MessageCenter.getMessageObservable(MessageType.SUB)); }
c、测试:
package com.pinnet; import com.pinnet.center.MessageCenter; public class Test { public static void main(String[] args) { MessageCenter.init(); MessageCenter.sendMessage(MessageCenter.MessageType.PUB, "pub"); MessageCenter.sendMessage(MessageCenter.MessageType.SUB, "sub"); } }
d、结果
六、观察者模式应用还是很不错的,特别是在分发数据,socket推送过后的数据分发处理等。当然不会离开消息队列,下一个博客将写到jms的用法。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
网站木马后门查杀工具Linux系统专用
后门这东西好让人头疼,第一文件太多了,不容易找,第二,难找,需要特征匹配啊。搞了一个python版查杀php webshell后门工具,大家可以增加后门的特征码,然后甩到后台给他查杀就可以了。适合Linux系统服务器的站长们 这个代码比较简单,大家可以自己继续完善下。主要是根据特征来匹配查找网站木马后门文件。 #!/usr/bin/python # -*- coding: utf-8 -*- #blog:www.sinesafe.com importos importsys importre rulelist =[ '(\$_(GET|POST|REQUEST)\[.{0,15}\]\(\$_(GET|POST|REQUEST)\[.{0,15}\]\))', '(_decode\([\'"][\w\+/=]{200,}[\'"]\))', 'eval\(_decode\(', '(eval\(\$_(POST|GET|REQUEST)\[.{0,15}\]\))', '(assert\(\$_(POST|GET|REQUEST)\[.{0,15}\]\))', '(\$[\w_]{...
- 下一篇
Python迭代器生成器,私有变量及列表字典集合推导式(二)
1 python自省机制 这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getattr(),hasattr(),isinstance(). a = [1,2,3] b = {'a':1,'b':2,'c':3} c = True print(type(a),type(b),type(c)) # <type 'list'> <type 'dict'> <type 'bool'> print(isinstance(a,list)) # True 2 python中列表推导式,字典推导式,集合推导式 列表生成式 : 中括号括起来表示列表 (1)[exp for iter_var in iterable if_exp] #工作过程: 1 迭代iterable中的每个元素,每次迭代都先判断if_exp表达式结果为真,如果为真则进行下一步,如果为假则进行下一次迭代; 2 把迭代结果赋值给iter_var,然后通过exp得到一个新的计算值; 3 最后...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- 设置Eclipse缩进为4个空格,增强代码规范
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Mario游戏-低调大师作品
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长