观察者模式
Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Observer(观察者)模式是比较常用的一个模式.
比如网上商店的产品价格发生了改变,需要向注册用户发送e-mail或者短信时,就可以用到Observer设计模式。
在此写了6个java类来描述说明Observer设计模式;
1、Observer.java 观察者接口
2、EmailSendObserver.java 邮差观察者
3、SMSSendObserver.java 短信发送观察者
4、Observable.java 被观察者基类
5、Product.java 被观察者(商品)
6、Test.java 带有main方法的测试类
================================= 1 Observer.java ===============================
public interface Observer {
void update(Observable o, Object arg);
}
================================= = 1 end ================================
======================== 2 EmailSendObserver.java ==========================
public class EmailSendObserver implements Observer {
//通过构造器的方式给Product注入邮件发送观察者
public EmailSendObserver(Product product) {
product.addObserver(this);
}
public void update(Observable product, Object arg) {
// TODO Auto-generated method stub
System.out.println("Product price has been changed to "
+ ((Product)product).getPrice()
+ " ;\n\t\t The notify e-mail has sent to all client.");
}
}
============================= 2 end =================================
========================= 3 SMSSendObserver.java ==============================
public class SMSSendObserver implements Observer {
//通过构造器的方式给Product注入短消息发送观察者
public SMSSendObserver(Product product) {
product.addObserver(this);
}
public void update(Observable product, Object arg) {
// TODO Auto-generated method stub
System.out.println("Product price has been changed to "
+ ((Product)product).getPrice()
+ " ;\n\t\t The notify SMS has sent to all client.");
}
}
============================= 3 end ==================================
========================== 4 Observable.java ==================================
public class Observable {
//state
private boolean changed = false;
//observer collection
private List<Observer> observers;
public Observable() {
observers = new ArrayList<Observer>(0);
}
//attach a oberver
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!observers.contains(o)) {
observers.add(o);
}
}
//detach a oberver
public synchronized void deleteObserver(Observer o) {
observers.remove(o);
}
//trigger all observers attached to this object observer to work
public void notifyObservers() {
notifyObservers(null);
}
//trigger all observers attached to this object observer to work
public void notifyObservers(Object arg) {
synchronized (this) {
if (!changed)
return;
clearChanged();
}
for (Observer observer : observers) {
observer.update(this, arg);
}
}
//Clears the observer list so that this object no longer has any observers.
public synchronized void deleteObservers() {
observers.clear();
}
//Marks this Observable object as having been changed;
protected synchronized void setChanged() {
changed = true;
}
//Indicates that this object has no longer changed, or that it has already
//notified all of its observers of its most recent change
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return observers.size();
}
}
============================= 4 end =============================
============================= 5 Product.java =============================
public class Product extends Observable {
//构造器
private Product(){}
//构造器
public Product(float price){
this.price = price;
}
//商品价格
private float price;
//改变商品价格
public void changePrice(float price) {
if (this.price != price) {
this.price = price;
setChanged();
}
notifyObservers();
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
========================== 5 end ======================================
======================== 6 Test.java ======================================
public class Test {
public static void main(String[] args) {
//new product
Product product = new Product(1000);
//email observer
new EmailSendObserver(product);
//sms observer
new SMSSendObserver(product);
//chage price of product
product.changePrice(800);
}
}
=========================== 6 end ====================================