java观察者(Observer)模式
观察者模式:
试想,在电子商务网站上,一个用户看中了一件一份,但是当时衣服的价格太贵,你需要将衣服收藏,以便等衣服降价时自动通知该用户。这里就是典型的观察模式的例子。
1.观察者模式的定义:
定义了一种对象之间的依赖关系,当一个对象(主题)发生改变时,它所有的依赖者(观察者)会收到主题状态改变的通知,并更新自己的状态。
试想,在电子商务网站上,一个用户看中了一件一份,但是当时衣服的价格太贵,你需要将衣服收藏,以便等衣服降价时自动通知该用户。这里就是典型的观察模式的例子。
1.观察者模式的定义:
定义了一种对象之间的依赖关系,当一个对象(主题)发生改变时,它所有的依赖者(观察者)会收到主题状态改变的通知,并更新自己的状态。
观察者模式让主题和观察者松耦合。主题不知道观察者的实现细节;任何时候在增加观察者的时候,可以随时增加,而不需要改变主题的代码,当然删除观察者也是一样。在开始的例子中,衣服便是主题(Subject),用户便是观察者(Observer),用户将衣服加收藏的过程便是观察者在主题注册那里的过程。
2.观察者模式的类图:
3.java提供了内置的观察者模式:Observer接口和Observerable类;为了理解观察模式,先不用这个内置方法,先用常规的方法实现以下上述例子:
package observer; //主题接口 public interface Subject { public void addObserver(Observer observer); public void deleteObserver(Observer observer); public void notifyObserver(); }
package observer; //观察者接口 public interface Observer { public double getOldPrice(); public void update(double price); }
package observer; /* * 具体的主题,concrete subject */ import java.util.ArrayList; import java.util.List; public class ClotheSubject implements Subject{ List<Observer> observers ; double price; public ClotheSubject() { observers = new ArrayList<>(); } @Override public void addObserver(Observer observer) { // TODO Auto-generated method stub observers.add(observer); } @Override public void deleteObserver(Observer observer) { // TODO Auto-generated method stub int index = (int)observers.indexOf(observer); if(index >= 0) observers.remove(index); } @Override public void notifyObserver() { // TODO Auto-generated method stub for(int i = 0;i < observers.size();i++) { Observer observer = (Observer)observers.get(i); observer.update(price); } } public void setPrice(double price) { this.price = price; notifyObserver(); } }
package observer; public class ClotheObserver implements Observer{ Subject subject; double price = 100.00d;//原始价格 public ClotheObserver(Subject subject) { this.subject = subject; subject.addObserver(this); } @Override public void update(double price) { // TODO Auto-generated method stub if(price<this.getOldPrice()) System.out.println("您上次看中衣服的价格变为:"+price+",请抓紧购买!"); this.price = price; } @Override public double getOldPrice() { // TODO Auto-generated method stub return price; } }测试代码:
package observer; public class Client_test { public static void main(String args[]) { ClotheSubject clothe_subject = new ClotheSubject(); Observer clothe_observer = new ClotheObserver(clothe_subject); clothe_subject.setPrice(10.00d); clothe_subject.setPrice(90.00d); clothe_subject.setPrice(20.00d); } }
4.java自身提供的内置观察者模式:java.util提供了observer接口和Observerable类,对象只需要实现观察者接口,便可以成为观察者,然后调用Observerable的addObserver方法,便加入主题中。下面是用内置观察者模式重新修改上例代码:
主题类:
package observer; /* * 具体的主题,concrete subject */ import java.util.Observable; public class ClotheSubject extends Observable{ double price; public ClotheSubject() { } public void priceChanged() { setChanged(); notifyObservers();//Observable中的方法,会调用观察者的update方法 } public void setPrice(double price) { this.price = price; priceChanged(); } public double getPrice() { return price; } }观察者类:
package observer; import java.util.Observable; import java.util.Observer; public class ClotheObserver implements Observer{ Observable observerable; double price = 100.00d; public ClotheObserver(Observable observerable) { this.observerable = observerable; //将自己注册为观察者 observerable.addObserver(this); } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub if(o instanceof ClotheSubject) { ClotheSubject clothesubject = (ClotheSubject)o; if(price > clothesubject.getPrice()) display(clothesubject.getPrice()); this.price = clothesubject.getPrice(); } } public void display(double price) { System.out.println("您上次看中衣服的价格变为:"+price+",请抓紧购买!"); } }测试代码:
package observer; public class Client_test { public static void main(String args[]) { ClotheSubject clothe_subject = new ClotheSubject(); ClotheObserver clothe_observer = new ClotheObserver(clothe_subject); clothe_subject.setPrice(90.00d); clothe_subject.setPrice(80.00d); } }