1. 觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。另:當一個對象的改變需要同時改變其他對象的時候,而且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。
2. 結構圖
3. 舉例:
A.抽象通知者
- public interface Publisher {
- public String state = null;
- public void register(Observer o);
- public void unregister(Observer o);
- }
B. 抽象觀察者
- public abstract class Observer {
- public abstract void update();
- }
C. 具體通知者
- public class ConcretPublisher1 implements Publisher{
- private List<Observer> observerList = new ArrayList<Observer>();
- public void register(Observer observer) {
- observerList.add(observer);
- }
- public void unregister(Observer observer) {
- observerList.remove(observer);
- }
- public void newNotify() {
- for(Observer observer : observerList) {
- observer.update();
- }
- }
- }
- public class ConcretPublisher2 implements Publisher{
- private List<Observer> observerList = new ArrayList<Observer>();
- public void register(Observer observer) {
- observerList.add(observer);
- }
- public void unregister(Observer observer) {
- observerList.remove(observer);
- }
- public void newNotify() {
- for(Observer observer : observerList) {
- observer.update();
- }
- }
- }
D.具體觀察者
- public class ConcreteObserver1 extends Observer{
- private Publisher publisher;
- private String name;
- public ConcreteObserver1(Publisher publisher,String name) {
- this.publisher = publisher;
- this.name = name;
- }
- @Override
- public void update() {
- // TODO Auto-generated method stub
- System.out.println("對"+name+"說:訂單支付成功,請求供貨方發貨");
- }
- public Publisher getPublisher() {
- return publisher;
- }
- public void setPublisher(Publisher publisher) {
- this.publisher = publisher;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class ConcreteObserver2 extends Observer{
- private Publisher publisher;
- private String name;
- public ConcreteObserver2(Publisher publisher,String name) {
- this.publisher = publisher;
- this.name = name;
- }
- @Override
- public void update() {
- // TODO Auto-generated method stub
- System.out.println("對"+name+"說:供貨方發貨成功,修改狀態吧!");
- }
- public Publisher getPublisher() {
- return publisher;
- }
- public void setPublisher(Publisher publisher) {
- this.publisher = publisher;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
4. 其他:
JDK提供對觀察者模式的內置支持。Observable類與Observer接口。下面是Observer模式的實現過程:
創建一個被觀察者,繼續java.util.Observable
創建一個觀察者,實現java.util.Observer接口
註冊觀察者,調用addObserver(Observer observer)
在被觀察者改變對象內部狀態的地方,調用setChanged()方法,然後調用 notifyObservers(Object)方法,通知被觀察者
在觀察者的update(Object)方法中,對改變做出響應。
代碼舉例:
- public class Watched extends Observable{
- private String data = "";
- public String retrieveData() {
- return data;
- }
- public void changeData(String data) {
- if(!this.data.equals(data)) {
- this.data = data;
- this.setChanged();
- }
- this.notifyObservers();
- }
- }
- public class Watcher implements Observer{
- public Watcher(Watched w) {
- w.addObserver(this);
- }
- @Override
- public void update(Observable ob, Object arg) {
- // TODO Auto-generated method stub
- System.out.println("Data has bean changed to :" + ((Watched)ob).retrieveData() + "");
- }
- }
- public class Tester {
- static private Watched watched;
- static private Observer watcher;
- public static void main(String[] args) {
- watched = new Watched();
- watcher = new Watcher(watched);
- watched.changeData("In c,we create bugs.");
- watched.changeData("In java,we inherit bugs.");
- watched.changeData("In java,we inherit bugs.");
- watched.changeData("In visual Basic,We visualize bugs.");
- }
- }
5. 應用場景:
A. 當訂單有退款的時候,需要做一系統的操作,商品自動下架或者合作方自動下架等。