Java内部实现的观察者模式小记
假如Admin要观察User的工资变化,当User的工资增加或者减少时,都会引起Admin输出相应的信息。
定义观察者接口:MyObserver.java
package cn.liuning.watch;
public interface MyObserver {
void update(MyObservable o, Object arg);
}
定义被观察者父类(Admin类需要继承这个类):MyObservable.java
package cn.liuning.watch; import java.util.Observer;
import java.util.Vector; /**
* 观察者模式,Java源码
* @author liuning
*
*/
public class MyObservable {
/**
* 标记是否被观察这改变
*/
private boolean changed = false; /**
* 保存所有的观察者
*/
private Vector<MyObserver> all; /**
* 观察者构造函数
*/
public MyObservable(){
all = new Vector<MyObserver>();
} /**
* 增加一个观察者
* @param o
*/
public synchronized void addObserver(MyObserver o){
if(o == null){
throw new NullPointerException();
}
if(!all.contains(o)){
all.addElement(o);
}
} /**
* 删除一个观察者
* @param o
*/
public synchronized void deleteObserver(Observer o) {
all.removeElement(o);
} /**
* 被观察这通知观察者做出相应的变化
*/
public void notifyObservers() {
notifyObservers(null);
} /**
* 被观察这通知观察者做出相应的变化
*/
public void notifyObservers(Object arg) { Object[] arrLocal;
synchronized (this) {
if (!changed){
return ;
}
arrLocal = all.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--){
((MyObserver)arrLocal[i]).update(this, arg);
}
} /**
* 删除所有观察者
*/
public synchronized void deleteObservers() {
all.removeAllElements();
} /**
* 设置被观察这发生变化
*/
protected synchronized void setChanged() {
changed = true;
} /**
* 清除变化
*/
protected synchronized void clearChanged() {
changed = false;
} /**
* 判断是否有变化
* @return boolean
*/
public synchronized boolean hasChanged() {
return changed;
} /**
* 计数,获取观察者个数
* @return
*/
public synchronized int countObservers() {
return all.size();
} }
定义观察者(需要实现MyObservable接口):Admin.java
package cn.liuning.watch;
public class Admin implements MyObserver{
@Override
public void update(MyObservable o, Object arg) {
User user = (User) o;
System.out.println(arg+"钱改变了");
System.out.println(user.toString());
}
}
定义被观察者(需要继承MyObserver):User.java
package cn.liuning.watch;
public class User extends MyObservable{
private int price = 0;
private String name = "张三";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
@Override
public String toString() {
return "User [price=" + price + ", name=" + name + "]";
}
public void setPrice(int price) {
this.price = price;
//设置工资发生变化
this.setChanged();
//通知观察者执行,内部就是调用所有观察者的update方法,通过接口实现。
this.notifyObservers(this.name);//可午餐也可有参
}
}
测试Main方法:Test.java
package cn.liuning.watch;
public class Test {
public static void main(String[] args) {
//被观察者初始化
User user = new User();
//增加一个观察者
user.addObserver(new Admin());
user.setName("李四");
//当价格改变时就会观察者就会执行update方法。
user.setPrice(100);
}
}
Java内部实现的观察者模式小记的更多相关文章
- Java常见设计模式之观察者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ...
- JAVA基础——设计模式之观察者模式
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...
- 《JAVA设计模式》之观察者模式(Observer)
在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ...
- Java内部DNS查询实现和参数设置
一.Java内部DNS查询 Java使用域名查询时,用的自己内部的域名实现机制,最后都是交给InetAddress去做DNS解析. 源码分析参考:http://blog.arganzheng.me/p ...
- Java设计模式之《观察者模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...
- c#:对两个字符串大小比较(不使用c#/java内部的比较函数),按升序排序
题目:首先需要实现一个函数:两个字符串大小比较(不得使用c#/java系统函数)的自定义函数:之后对一个字符串数据进行按升序排序(在排序过程中使用字符串大小比较时,使用自定义的字符串大小比较函数). ...
- Python学习---Java和Python的区别小记
Java和Python的区别小记 注意这里使用的是 and/or/not 非java中的&&,||,!Java中的true是小写 Python中函数就是对象,函数和我们之前的[1,2 ...
- Java设计模式百例 - 观察者模式
观察者(Observer)模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主体对象的状态变化会通知所有观察者对象.观察者模式又叫做发布-订阅(Publish/Subscribe ...
- Java内部锁的可重用性(Reentrancy)
Java提供了强制原子性的内部锁机制:synchronized块.但是内部锁是可重入的,当线程试图获得它自己占有的锁时,请求会成功. 简单的说,就是在一个synchronized方法内部调用本类的其他 ...
随机推荐
- WP8_检测列表是否滑动
One of the UI features of lists on Windows Phone 7 is that the "scroll bars" don't really ...
- nginx之keepalive
一:设置 keepalive_timeout 0; 发curl: [xxx ~]$ curl -H "Keep-Alive: 60" -H "Connection: k ...
- HBase简介(很好的梳理资料)
http://www.tuicool.com/articles/iieIz2 一. 简介 history started by chad walters and jim 2006.11 G re ...
- Android IOS WebRTC 音视频开发总结(四三)-- 诚信交易案例分享
本文主要记录一些诚信交易的案例(两个陌生人之间没有合同,没有订金,没有讨价还价,完全靠诚信完成的交易), 特别纪录下来并不是因为金额有多高,而是因为在现在这种社会要完成这样的交易太难,特别是像咨询这种 ...
- Jquery入门之---------基本事件------------
Javascript有一个非常重要的功能,就是事件驱动. 当页面完成加载后,用户通过鼠标或键盘触发页面中绑定事件的元素即可触发.Jquery为开发者更有效率的编写事件行为,封装了大量有益的事件方法供我 ...
- Linux使用有线上网教程
本人亲测Linux(Ubuntu kylin 14.04)有线上网方法,下面是步骤: 一,运行Terminal(终端),输入 sudo pppoeconf 命令,设置账号和密码后,其他的全选yes ...
- POJ C++程序设计 编程题#2 编程作业—多态与虚函数
编程题#2 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 下面程序的输出结果 ...
- Linux下vi编辑器粘贴复制剪切功能
RedHat 9.0 Linux下vi编辑器实现简单的粘贴复制剪切功能": 如果想把文件内的第三行内容黏贴到第十五行: 1.进入你的文件,(处于命令模式,而不是编辑模式) 2.将你的光标移到 ...
- Windows Server 2003 增加远程用户个数
1.进入“开始”-“控制面板”-“添加或删除程序”如下图: 2.点击“添加/删除windows组件(A)”,进入如下图 如果该服务器没有安装“终端服务器”和“终端服务器授权”组件的话,则需要使用系统光 ...
- C#获取本周周一的日期
/// <summary> /// 获取本周的周一日期 /// </summary> /// <returns></returns> public st ...