我爱编程

设计模式-观察者模式(十七)

2018-05-27  本文已影响0人  巨子联盟

观察者(Observer)模式,又叫 发布-订阅(Publish/Subscribe)模式,模型-视图(Model-View)模式
定义了一种一对多的依赖关系,当主题对象发生改变的时候会通知所有的观察者对象。

一个变化其他的相应变化
设计目标:低耦合 + 行动的协调一致

上类图:


观察者模式.png

java类库对该模式的支持:
java JDK中定义了Observer接口,以及 Observable的主题角色


AWT1.1+,Servlet的委派事件模型(DEM Delegation Event Model)


优缺点:
优点:观察者和被观察者建立了一个抽象的耦合
缺点:

  1. 如果观察者比较多,全部通知一下比较耗时
  2. 如果被观察者之间有循环依赖会导致系统崩溃

  1. 定义个抽象观察者对象,可以直接用JDK自带的Observer接口
package com.byedbl.observer;

/**
 *  Observer interface
 */
public interface Observer {
    public void update(Subject s);
}
  1. 实现两个观察者
package com.byedbl.observer;
/**
 *  A concrete observer
 *  This concrete observer can change subject through call
 *  a concrete subject setState function
 */
import java.util.Vector;

public class ObserverA implements Observer {
    private Vector strVector;
    private Subject sub;
    public ObserverA(Subject s) {
        sub = s;
        //strVector = new Vector();
    }
    public void update(Subject subject) {
        strVector = subject.getState();
        System.out.println("----- ObserverA will be updated -----");
        for(int i = 0; i < strVector.size(); i++) {
            System.out.println("Num " + i + " is :" + (String)strVector.get(i));
        }
    }
    public void change(String action, String str) {
        sub.setState(action, str);
        //we can auto update
        //sub.sendNotify();
    }
    public void notifySub() {
        sub.sendNotify();
    }
}
package com.byedbl.observer; /**
 *  A concrete observer
 *  This observer, can not change subject, 
 *  but it can print the content in vector sorted by alphameric
 */
import java.util.Vector;

public class ObserverB implements Observer {
    private Vector strVector;
    public ObserverB() {
        strVector =  new Vector();
    }
    public void update(Subject subject) {
        strVector = (Vector)(subject.getState()).clone();
        //-----  Sorted vector  ---------------------------
        for (int i = strVector.size(); --i >= 0; ) {
            for (int j = 0; j < i; j++) {
                String str1 = (String)strVector.get(j);
                String str2 = (String)strVector.get(j+1);
                if((str1.compareTo(str2)) > 0) {
                    strVector.setElementAt(str2, j);
                    strVector.setElementAt(str1, j+1);
                }
            }
        }
        System.out.println("----- ObserverB will be updated -----");
        for(int i = 0; i < strVector.size(); i++) {
            System.out.println("Num " + i + " is :" + (String)strVector.get(i));
        }
    }
    
}
  1. 定义抽象主题角色
package com.byedbl.observer; /**
 *  Subject interface
 *  In this interface , we can only declare top 3 function, 
 *  other function we can define in an abstract class which implements
 *  this interface
 */
import java.util.*;

public interface Subject  {
    public abstract void attach(Observer o);
    public abstract void detach(Observer o);
    public abstract void sendNotify();

    public abstract Vector getState();
    public abstract void setState(String act, String str);
}
  1. 实现抽象主题角色
package com.byedbl.observer;
/**
 * A concrete subject
 */

import java.util.LinkedList;
import java.util.Vector;

public class ConcreteSubject implements Subject {
    private LinkedList observerList;
    private Vector strVector;

    public ConcreteSubject() {
        observerList = new LinkedList();
        strVector = new Vector();
    }

    public void attach(Observer o) {
        observerList.add(o);
    }

    public void detach(Observer o) {
        observerList.remove(o);
    }

    public void sendNotify() {
        for (int i = 0; i < observerList.size(); i++) {
            ((Observer) observerList.get(i)).update(this);
        }
    }

    public void setState(String act, String str) {
        if (act.equals("ADD")) {
            strVector.add(str);
        } else if (act.equals("DEL")) {
            strVector.remove(str);
        }
    }

    public Vector getState() {
        return strVector;
    }
}
  1. 客户端代码
package com.byedbl.observer;
/**
 * A concrete subject
 */

import java.util.LinkedList;
import java.util.Vector;

public class ConcreteSubject implements Subject {
    private LinkedList observerList;
    private Vector strVector;

    public ConcreteSubject() {
        observerList = new LinkedList();
        strVector = new Vector();
    }

    public void attach(Observer o) {
        observerList.add(o);
    }

    public void detach(Observer o) {
        observerList.remove(o);
    }

    public void sendNotify() {
        for (int i = 0; i < observerList.size(); i++) {
            ((Observer) observerList.get(i)).update(this);
        }
    }

    public void setState(String act, String str) {
        if (act.equals("ADD")) {
            strVector.add(str);
        } else if (act.equals("DEL")) {
            strVector.remove(str);
        }
    }

    public Vector getState() {
        return strVector;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读