一个男人的设计模式:观察者模式

1.观察者模式原理

定义:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化。通常一个Subject对象对应多个Observer对象,且Observer对象对Subject中某个状态具有一依赖性(也就是说,当Subject的某个状态变化时,Observer会执行不同的操作)

1.1 类图

在这里插入图片描述

1.2 角色

Subject(主题):它把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject(具体主题):将有关状态存入具体主题对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
Observer(观察者):观察者父类。
ConcreteObserver(具体观察者):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。


2.观察者模式示例

2.1 背景(过红绿灯)

Subject:主题为红绿灯
Observer:观察者为车和认

2.2 代码

2.2.1 Subject(抽象类)

该类定义了对观察者对象集合的处理操作

public abstract class Subject {

    //观察者对象引用的集合
    private List<Observer> observers = new ArrayList<Observer>();

    //添加监视器
    public void attach(Observer observer) {
        if (observer == null) {
            return;
        }
        observers.add(observer);
    }

    //删除监视器
    public void detach(Observer observer) {
        Iterator<Observer> iterator = observers.iterator();
        while (iterator.hasNext()) {
            Observer next = iterator.next();
            if (observer.equals(next)) {
                iterator.remove();
            }
        }
    }

    //通知观察者(该应用中特指:通知观察者(人或者车)通行)
    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.deal(this);
        }
    }
}

2.2.2 ConcreteSubjectTrafficLights(红绿灯)

该类定义了自身一些状态信息,这特指红绿灯的颜色(红和绿)

public class ConcreteSubjectTrafficLights extends Subject{
    //红灯停,绿灯行,黄灯缓
    private String color = "red";

    public String getColor() {
        return color;
    }
    //更新红绿灯的颜色,红或者绿
    public void update(String color){
        this.color = color;
    }
}

2.2.3 Observer(抽象观察者)

public interface Observer {
    public void deal(Object o);
}

2.2.4 ConcreteObserverMan(观察者人)

public class ConcreteObserverMan implements Observer {

    public void deal(Object o) {
        if(o instanceof ConcreteSubjectTrafficLights){
            String color = ((ConcreteSubjectTrafficLights) o).getColor();
            if(color.equalsIgnoreCase("red")){
                System.out.println("man 步行过马路");
            }else{
                System.out.println("man 等灯变绿");
            }
        }
    }
}

2.2.5 ConcreteObserverCar(观察者车)

public class ConcreteObserverCar implements Observer{
    public void deal(Object o) {
        if(o instanceof ConcreteSubjectTrafficLights){
            String color = ((ConcreteSubjectTrafficLights) o).getColor();
            if(color.equalsIgnoreCase("red")){
                System.out.println("car 正常通行");
            }else{
                System.out.println("car 等灯变绿");
            }
        }
    }
}

2.2.6 Client(测试与使用)

public class Client {
    public static void main(String[] args) {
        //具体的红绿灯对象(Subject)
        ConcreteSubjectTrafficLights subject = new ConcreteSubjectTrafficLights();
        ConcreteObserverCar concreteObserverCar = new ConcreteObserverCar();
        ConcreteObserverMan concreteObserverMan = new ConcreteObserverMan();
        subject.attach(concreteObserverCar);
        subject.attach(concreteObserverMan);
        System.out.println("_____________init_____________");
        //初始状态通知观察红绿灯的具体观察者(人和车)
        subject.notifyObserver();
        System.out.println("__________color change________");
        //具体对象状态变化(红绿灯,灯颜色变化了)
        subject.update("green");
        //再次通知观察红绿灯的具体观察者(人和车)
        subject.notifyObserver();
        System.out.println("__detach concreteObserverMan___");
        //移除某个观察者
        subject.detach(concreteObserverMan);
        //再次发通知
        subject.notifyObserver();
    }
}

output

_____________init_____________
car 正常通行
man 步行过马路
__________color change________
car 等灯变绿
man 等灯变绿
__detach concreteObserverMan___
car 等灯变绿

通过以上的代码示例及注释,相信你对观察者模式有了一个比较清晰的认识,这边建议你再回头看一下1.2 角色,就会有更深入的理解。

3.JDK观察者模式

JDK内建了观察者模式的相关支持类

3.1 Observable(等价Subject,被观察者)

package:java.util.Observable
相比于我们自己写的Subject抽象类,它采用了Vector作为观察者集合对象
在这里插入图片描述
同样的Observable其中也定义了一些操作观察者集合的方法,方法比较简单,这些方法大都采用同步的方式实现。
在这里插入图片描述

3.2 Observer(观察者)

package:java.util.Observer

/**
 * A class can implement the <code>Observer</code> interface when it
 * wants to be informed of changes in observable objects.
 *
 * @author  Chris Warth
 * @see     java.util.Observable
 * @since   JDK1.0
 */
public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}

以上摘自jdk源码,定义了观察者的updata方法
第一个参数Observable o,表示被观察者对象
第二个参数Object arg,表示Observable对象的notifyObservers方法的参数

4.小结

观察者模式通过1对n的组合形式将被观察者的状态变化同步到观察者中,观察者根据被观察者的状态执行具体的处理逻辑。
优点:观察者和主题对象松耦合,两者可以先对独立的扩展和变化,比如可以很方便的增删观察者,修改观察者中的更新逻辑而不用修改主题中的代码。
缺点:
1.Subject(抽象主题)需要依赖Observer(抽象观察者),而这种依赖关系完全可以去除。
2.主题需要维护观察者列表,并对外提供动态增删观察者的接口,
3.主题状态改变时需要由自己去通知观察者进行更新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值