(10).观察着模式Observer
文章链接:http://lykke.iteye.com/blog/1309952
是希望两个(或多个)对象,我们称之为Subject和Observer,当一方的状态发生改变的时候,
另一方能够得到通知。也就是说,作为Observer的一方,能够监视到Subject的某个特定的状态变化,
并为之做出反应。一个简单的例子就是:当一个用户视图中的数据被用户改变后,后端的数据库能够得到更新,
而当数据库被其他方式更新后,用户视图中的数据显示也会随之改变。
观察者模式实际上没什么高深的东西,就是运用了java的继承和接口,在被观察者的抽象类里设置一个状态标志,
通过该标志判断是否通知观察者对象。在学习该模式的同时,
我们更应该学习java的继承和接口的灵活应用,其实所有的设计模式都是继承、接口、多态的灵活应用
package com.createtype.desginpatterns.observer;
import java.util.Observable;
public class Book extends Observable {
private String name = "";
private double price = 0.0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// 当书的价格修改时调用该方法
public void modifyPrice(Book b) {
// 调用父类的方法,改变被观察者的状态
setChanged();
// 通知客户该书已降价
notifyObservers(b);
}
}
package com.createtype.desginpatterns.observer;
import java.util.Observable;
import java.util.Observer;
public class BuyerEmail implements Observer {
private String buyerId = "";
private String email = "";
public String getBuyerId() {
return buyerId;
}
public void setBuyerId(String buyerId) {
this.buyerId = buyerId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// 该方法会被“被观察者的父类”既Observable调用
public void update(Observable o, Object arg) {
// 这里做具体发电子邮件的操作
Book b = (Book) arg;
System.out.println("给顾客的发电子邮件:" + b.getName() + "降价了,目前价格为:"
+ b.getPrice());
}
}
package com.createtype.desginpatterns.observer;
import java.util.Observable;
import java.util.Observer;
public class BuyerMobileMessage implements Observer {
private String buyerId = "";
private String mobileNo = "";
public String getBuyerId() {
return buyerId;
}
public void setBuyerId(String buyerId) {
this.buyerId = buyerId;
}
public String getMobileNo() {
return mobileNo;
}
public void setMobileNo(String mobileNo) {
this.mobileNo = mobileNo;
}
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
Book b = (Book) arg;
System.out.println("给顾客的发手机短信:" + b.getName() + "降价了,目前价格为:"
+ b.getPrice());
}
}
package com.createtype.desginpatterns.observer;
/**
* 输出:
给顾客的发电子邮件:<<Java设计模式>>降价了,目前价格为:45.0
给顾客的发手机短信:<<Java设计模式>>降价了,目前价格为:45.0
不知道上面的例子你看懂了没有,观察者模式实际上没什么高深的东西,就是运用了java的继承和接口,
在被观察者的抽象类里设置一个状态标志,通过该标志判断是否通知观察者对象。
在学习该模式的同时,我们更应该学习java的继承和接口的灵活应用,其实所有的设计模式都是继承、接口、多态的灵活应用
*
*
*/
public class MainApp {
public static void main(String args[])
{
Book b1 = new Book();
b1.setName("<<Java设计模式>>");
b1.setPrice(45.00);// 假设原价是60,现在是降价促销
// 下面的观察者在实际的应用中可以从数据库或文件中读取
BuyerMobileMessage bm = new BuyerMobileMessage();
bm.setBuyerId("001");
bm.setMobileNo("13810500085");
BuyerEmail be = new BuyerEmail();
be.setBuyerId("001");
be.setEmail("dobodo@163.com");
// 增加观察者,在实际应用中就是那些人对该书做了关注
b1.addObserver(bm);
b1.addObserver(be);
b1.modifyPrice(b1);
}
}
package com.createtype.desginpatterns.observer;
import java.util.Observer;
import java.util.Vector;
public class Observable {
private boolean changed = false;
private Vector obs;
// 创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。
public Observable() {
obs = new Vector();
}
/**
*
* 添加观察者到观察者列表中去
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
*
* 删除一个观察者
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
public void notifyObservers() {
notifyObservers(null);
}
/**
* 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用
*/
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length - 1; i >= 0; i--){
//((Observer) arrLocal[i]).update(this, arg);
}
}
public synchronized void deleteObservers() {
obs.removeAllElements();
}
protected synchronized void setChanged() {
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return obs.size();
}
}
package com.createtype.desginpatterns.observer;
public interface Observer {
void update(Observable o, Object arg);
}