假如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内部实现的观察者模式小记的更多相关文章

  1. Java常见设计模式之观察者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ...

  2. JAVA基础——设计模式之观察者模式

    观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...

  3. 《JAVA设计模式》之观察者模式(Observer)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ...

  4. Java内部DNS查询实现和参数设置

    一.Java内部DNS查询 Java使用域名查询时,用的自己内部的域名实现机制,最后都是交给InetAddress去做DNS解析. 源码分析参考:http://blog.arganzheng.me/p ...

  5. Java设计模式之《观察者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...

  6. c#:对两个字符串大小比较(不使用c#/java内部的比较函数),按升序排序

    题目:首先需要实现一个函数:两个字符串大小比较(不得使用c#/java系统函数)的自定义函数:之后对一个字符串数据进行按升序排序(在排序过程中使用字符串大小比较时,使用自定义的字符串大小比较函数). ...

  7. Python学习---Java和Python的区别小记

    Java和Python的区别小记 注意这里使用的是 and/or/not  非java中的&&,||,!Java中的true是小写 Python中函数就是对象,函数和我们之前的[1,2 ...

  8. Java设计模式百例 - 观察者模式

    观察者(Observer)模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主体对象的状态变化会通知所有观察者对象.观察者模式又叫做发布-订阅(Publish/Subscribe ...

  9. Java内部锁的可重用性(Reentrancy)

    Java提供了强制原子性的内部锁机制:synchronized块.但是内部锁是可重入的,当线程试图获得它自己占有的锁时,请求会成功. 简单的说,就是在一个synchronized方法内部调用本类的其他 ...

随机推荐

  1. windows 2003 修改远程桌面连接数详细方法

    Windows Server 2003默认情况下允许远程终端连接的数量是2个用户,我们可以根据需要适当增加远程连接同时在线的用户数. 单击“开始→运行”,输入“gpedit.msc”打开组策略编辑器窗 ...

  2. 05-Tom猫(UIImageView的简单运用)

    ViewController.h文件中: @interface ViewController : UIViewController @property (weak, nonatomic) IBOutl ...

  3. 在PeopleSoft系统中实现打印页面的功能

    我们知道,在PeopleSoft HCM里,一般上了薪酬模块的话,都会客户化工资单页面,去匹配公司之前的工资单的报表的格式.有的时候,这个工资单页面又需要打印出来,以供员工的使用.PeopleSoft ...

  4. c#使用DocX给word添加目录TOC

    刚要做目录的时候,我就想DocX应该提供了这个方面的函数.于是我就在讨论区搜索,看看别人是怎么用的. 我搜索了catalog; catalogue; list; contents;,但是都没有和目录有 ...

  5. Visual Studio 2010 更新NuGet Package Manager出错解决办法

    在Visual Studio 2010的扩展管理器中发现NuGet Package Manger有最新版本更新提示,选择更新安装提示以下错误信息: 2013/4/25 1:11:48 - Micros ...

  6. mongodb基础用法

    安装部分 mongodb配置方法 mongodb的安装目录 C:\MongoDB\Server\3.2\bin 创建以下目录 c:\mongo\log c:\mongo\db 创建mongodb的配置 ...

  7. js中settimeout方法加参数

    js中settimeout方法加参数的使用. 简单使用看w3school  里面没有参数调用,  例子: <script type="text/javascript"> ...

  8. python解析xml模块封装代码

    在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...

  9. 第四章 管理程序流(In .net4.5) 之 事件和回调

    1. 概述 本章讲解如何使用 委托.lambda表达式 和 匿名方法 来创建和使用事件. 2. 主要内容 2.1 理解委托 委托是一种用方法签名形式定义的类型.可以让它指向其他方法,可以通过它调用其他 ...

  10. SRF之数据字典

      框架提供数据字典的配置和显示的功能 字典以编码作为标识,用varchar(50)类型保存字典的编码.   字典的用法 1.在代码里边需要查询字典信息的 可用 Components.DataDict ...