- 前面讲了观察者模式的“推”数据的方式,接下来时观察者模式的“拉”数据方式。
拉数据方式是指具体主题不将变化后的数据交给具体观察者,而是提供获得这些数据的方法,具体主题在得到通知后,调用具体主题的方法更新自己的数据(即观察者把数据拉过来)。
例子,一家商店发布打折商品信息,包括商品的价格、折后价、名称。有两位顾客,一位关注打折的商品,另一位关心商品折后价格。
/**
*
*/
package org.rico.pattern.demo.observer2;
/**
* @author rico 2013-3-3
* 主题:定义具体主题需要实现的方法,如:添加、删除、通知观察者的方法。
*/
public interface Subject {
/**
* 新增观察者
* @param observer
*/
public void add(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void delete(Observer observer);
/**
* 主题通知观察者更新数据
*/
public void notifyObserver();
}
/**
*
*/
package org.rico.pattern.demo.observer2.impl;
import java.util.ArrayList;
import java.util.List;
import org.rico.pattern.demo.observer2.Observer;
import org.rico.pattern.demo.observer2.Subject;
/**
* @author rico 2013-3-3
*
*/
public class ShopSubject implements Subject {
private List<Observer> observers = null;
private int oldPrice, newPrice;
private String goodName;
public ShopSubject() {
observers = new ArrayList<Observer>();
}
/* (non-Javadoc)
* @see org.rico.pattern.demo.observer.Subject#add(org.rico.pattern.demo.observer.Observer)
*/
@Override
public void add(Observer observer) {
if(!observers.contains(observer)) {
observers.add(observer);
}
}
/* (non-Javadoc)
* @see org.rico.pattern.demo.observer.Subject#delete(org.rico.pattern.demo.observer.Observer)
*/
@Override
public void delete(Observer observer) {
if(observers.contains(observer)) {
observers.remove(observer);
}
}
/* (non-Javadoc)
* @see org.rico.pattern.demo.observer.Subject#notifyObserver()
*/
@Override
public void notifyObserver() {
for(Observer ob : observers) {
ob.update();
}
}
//设置商品信息
public void setGoods(String goodName, int oldPrice, int newPrice) {
this.setGoodName(goodName);
this.setOldPrice(oldPrice);
this.setNewPrice(newPrice);
this.notifyObserver();
}
public List<Observer> getObservers() {
return observers;
}
public void setObservers(List<Observer> observers) {
this.observers = observers;
}
public int getOldPrice() {
return oldPrice;
}
public void setOldPrice(int oldPrice) {
this.oldPrice = oldPrice;
}
public int getNewPrice() {
return newPrice;
}
public void setNewPrice(int newPrice) {
this.newPrice = newPrice;
}
public String getGoodName() {
return goodName;
}
public void setGoodName(String goodName) {
this.goodName = goodName;
}
}
/**
*
*/
package org.rico.pattern.demo.observer2;
/**
* @author rico 2013-3-4
* 观察者
*/
public interface Observer {
public void update();
}
/**
*
*/
package org.rico.pattern.demo.observer2.impl;
import org.rico.pattern.demo.observer2.Observer;
import org.rico.pattern.demo.observer2.Subject;
/**
* @author rico 2013-3-4
* 顾客(具体观察者)
*/
public class CustomerOne implements Observer {
private Subject subject;
private String name;
public CustomerOne(Subject subject, String name) {
this.subject = subject;
this.name = name;
subject.add(this);
}
/* 顾客从商店“拉去”数据,更新自己的数据(non-Javadoc)
* @see org.rico.pattern.demo.observer2.Observer#update()
*/
@Override
public void update() {
if(subject instanceof ShopSubject) {
ShopSubject su = (ShopSubject) subject;
System.out.println("顾客:" + name + ",");
System.out.println("只对商品名称感兴趣,");
System.out.println("商品名称:" + su.getGoodName());
} else {
System.out.println("获取到任何数据...");
}
}
}
/**
*
*/
package org.rico.pattern.demo.observer2.impl;
import org.rico.pattern.demo.observer2.Observer;
import org.rico.pattern.demo.observer2.Subject;
/**
* @author rico 2013-3-4
* 顾客(具体观察者)
*/
public class CustomerTwo implements Observer {
private Subject subject;
private String name;
public CustomerTwo(Subject subject, String name) {
this.subject = subject;
this.name = name;
subject.add(this);
}
/* 顾客从商店“拉去”数据,更新自己的数据(non-Javadoc)
* @see org.rico.pattern.demo.observer2.Observer#update()
*/
@Override
public void update() {
if(subject instanceof ShopSubject) {
ShopSubject su = (ShopSubject) subject;
System.out.println("顾客:" + name + ",");
System.out.println("只对商品价格感兴趣,");
System.out.println("商品价格:" + su.getNewPrice() + "-" + su.getOldPrice());
} else {
System.out.println("获取到任何数据...");
}
}
}
/**
*
*/
package org.rico.pattern.demo.observer2;
import org.rico.pattern.demo.observer2.impl.CustomerOne;
import org.rico.pattern.demo.observer2.impl.CustomerTwo;
import org.rico.pattern.demo.observer2.impl.ShopSubject;
/**
* @author rico 2013-3-3
*
*/
public class ObserverTest {
/**
* @param args
*/
public static void main(String[] args) {
ShopSubject subject = new ShopSubject();
Observer university = new CustomerOne(subject, "rico");
Observer haigui = new CustomerTwo(subject, "admin");
System.out.println("###################感冒999#######################");
subject.setGoods("感冒999", 10, 8);
System.out.println("###################可口可乐#######################");
subject.setGoods("可口可乐", 6, 5);
}
}