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

观察者(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;
    }
}

推荐阅读更多精彩内容

  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 2,416评论 1 15
  • 【学习难度:★★★☆☆,使用频率:★★★★★】直接出处:观察者模式梳理和学习:https://github.com...
    BruceOuyang阅读 946评论 1 5
  • 本文的结构如下: 什么是观察者模式 为什么要用该模式 模式的结构 代码示例 推模型和拉模型 优点和缺点 适用环境 ...
    w1992wishes阅读 897评论 0 17
  • 中国茶叶的分类,大致根据发酵程度或者制作工艺而分成了六大主类,相对于绿茶红茶等常见的茶类,我们还有一个既熟悉又陌生...
    茶人未晓師古坊主人阅读 128评论 2 2
  • 高中时已读过几遍《红楼梦》,然而心中一直带着遗憾。不得不把心思放在考点上,没有机会自由感悟它的韵味。所以,我又打开...
    繁缕_2991阅读 89评论 0 1