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方法内部调用本类的其他 ...
随机推荐
- Win8系统安装NET Framework 3.5的方法
1)找到下载过的Win8系统盘,解压到某个目录下,例如 F:, 找到解压的系统盘目录中"sources\sxs"文件夹 2)以管理员身份运行cmd命令,执行下面的命令: dism. ...
- SQL更新表的字段
Oracle: alter table CAPIAGENTLOG modify(clientcode nvarchar2()) SQL Server: alter table CAPIAGENTLOG ...
- CSS3 图片悬浮缩放效果
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- 由后序遍历结果构造二叉查找树 && 二叉查找树链表化
二叉查找树通俗说就是左孩子比父亲小,右孩子比父亲大.构造这么一个树,树嘛,递归即可. 例如一棵树后序遍历是这样(下图的树):2 9 8 16 15 10 25 38 45 42 30 20.最后的20 ...
- Oracle VM VirtualBox 设置本机与虚拟机共享文件
文章转载自http://wenku.baidu.com/link?url=5uZ1xWnGC55FGW2XUqzLVdttRcik2xCqwRKEdh6z-nZJ63UQn3j2750ES_q4Oro ...
- iOS中UIKit——UIDataDetectors(数据检测器)它将电话、邮件、网址等变为链接
1.它用于UITextView和UIWebView,属性名为:dataDetetorTypes 2.此属性可以设定使符合电话.邮件.网址.符合格式的日期等文字变为链接文字. 3.电话号码点击后拨出电话 ...
- C#语法基础和面向对象编程
1.C#语法基础 http://www.cnblogs.com/tonney/archive/2011/03/16/1986456.html 2.C#与面向对象基础 很棒的资源,简明扼要,介绍的非常清 ...
- 透过c的编程原则,来规范自己现在的一些编程习惯
1.合理的使用注释 注释为:/*…………*/ 注释有以下几种情况: 1) 版本.版权声明. 2) 函数接口说明. 3) 重要的代码或者段落显示. 注释注意: 1) 注释是对代码的解释,不是对文档.注释 ...
- GUID,UUID
<? class System { function currentTimeMillis() { list($usec, $sec) = explode(" ",microt ...
- How to using to code import to GL journal[AX2012]
static void THK_importLedgerJournalTrans(Args _args) { Filename fileName = "C:\\Users\\ksiu3880 ...