读设计模式之禅--观察者模式

  • 定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。即:
  • 监视和被监视 模式
  • 订阅发布模式

监视模式:

package com.example.spring.design.Observer;
import java.util.ArrayList;

/**
 * @Author: hyh
 * @Date: 2021/12/8 9:46
 * 抽象一个被监视者
 **/
public abstract class Monitored  {
    // 监视人
    private ArrayList<Monitor> monitors = new ArrayList<>();

    // 添加监视人
    public boolean register(Monitor m) {
        this.monitors.add(m);
        return true;
    }
    // 删除监视人
    public boolean remove(Monitor m) {
        boolean contains = this.monitors.contains(m);
        if (contains) {
            this.monitors.remove(m);
            return true;
        }
        return false;
    }
    //通知
    public void notifying(String s) {
        for (Monitor  m: monitors) {
            m.notifying(s);
        }
    }
}
// 监视女朋友
class Girl extends Monitored{
   
    public void eat(){
        super.notifying("女朋友开始吃饭了");
    }
}

/**
 * @Author hyh
 * @Date 9:48 2021/12/8
 * 抽象一个监视者
 **/
abstract class Monitor {
    abstract void notifying(String s);
}
// 1号男朋友
class Boy1 extends Monitor{
    @Override
    void notifying(String s) {
        System.out.println(s);
    }
}
// 2号男朋友
class Boy2 extends Monitor{
    @Override
    void notifying(String s) {
        System.out.println(s);
    }
}
class Tset{
    public static void main(String[] args) {
        Girl girl = new Girl();
        Boy1 boy1 = new Boy1();
        //Boy2 boy2 = new Boy2();
        //添加监视人1
        girl.register(boy1);
        girl.eat();
    }
}

输出:
女朋友开始吃饭了

订阅发布:

package com.example.spring.design.Observer;

import java.util.ArrayList;

/**
 * @Author: hyh
 * @Date: 2021/12/8 14:01
 * 定义主题接口
 **/
public interface Subject {

    // 订阅
    void register(Observer m);

    // 取消
    void remove(Observer m);

    //通知
    void notifying(Subject s);

    void display();

}

class AV implements Subject {

    private String name;
    private String url;

    // 监视人
    private ArrayList<Observer> obs = new ArrayList<>();

    @Override
    public void register(Observer m) {
        this.obs.add(m);
    }

    @Override
    public void remove(Observer m) {
        boolean contains = this.obs.contains(m);
        if (contains) {
            this.obs.remove(m);
        }
    }

    // 更新资源
    public void update(String name, String url) {
        this.name = name;
        this.url = url;
        this.notifying(this);
    }

    @Override
    public void notifying(Subject s) {
        for (Observer ob : obs) {
            ob.update(s);
        }
    }

    @Override
    public void display() {
        System.out.println(this.name);
        System.out.println(this.url);
    }
}


interface Observer {
    void update(Subject o);
}

class Ds1 implements Observer {

    @Override
    public void update(Subject o) {
        o.display();
    }
}

class Test {
    public static void main(String[] args) {
        // AV 频道
        AV av = new AV();
        // 屌丝
        Ds1 ds1 = new Ds1();
        // 订阅
        av.register(ds1);
        av.update("苍老师视频", "地址:www.caolaoshi.com");

    }
}
输出:
苍老师视频
地址:www.caolaoshi.com

java.util包提供一个接口 一个类 咱可以实现接口 继承类来实现观察者模式,但是有很多缺点:


package java.util;


public interface Observer {
  
    void update(Observable o, Object arg);
}



package java.util;
public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    /** Construct an Observable with zero Observers. */

    public Observable() {
        obs = new Vector<>();
    }


    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }


    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

 
    public void notifyObservers() {
        notifyObservers(null);
    }

  
    public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    /**
     * Clears the observer list so that this object no longer has any observers.
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    /**
     * Marks this <tt>Observable</tt> object as having been changed; the
     * <tt>hasChanged</tt> method will now return <tt>true</tt>.
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    /**
     * Indicates that this object has no longer changed, or that it has
     * already notified all of its observers of its most recent change,
     * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
     * This method is called automatically by the
     * <code>notifyObservers</code> methods.
     *
     * @see     java.util.Observable#notifyObservers()
     * @see     java.util.Observable#notifyObservers(java.lang.Object)
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    /**
     * Tests if this object has changed.
     *
     * @return  <code>true</code> if and only if the <code>setChanged</code>
     *          method has been called more recently than the
     *          <code>clearChanged</code> method on this object;
     *          <code>false</code> otherwise.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#setChanged()
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * Returns the number of observers of this <tt>Observable</tt> object.
     *
     * @return  the number of observers of this object.
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

java.util.Observable的确点:
Observable是一个“类”而不是一个“接口”,更糟的是,它甚至没有实现一个接口。不幸的是,java.util.Observable的实现有许多问题,限制了它的使用和复用。这并不是说它没有提供有用的功能,我们1只是想提醒大家注意一些事实。
Observable是一个类
你已经从我们的原则中得知这不是一件好事,但是,这到底会造成什么问题呢?首先,因为Observablc是一个“类”,你必须设计一个类继承它。如果某类想同时具有Observable类和另一个超类的行为,就会陷入两难,毕竞Java不支持多重继承。这限制了Observable的复用潜力
再者,因为没有Observable接口,所以你无法建立自己的实现,和Java内置的Observer API搭配使用,也无法将java.util的实现换成另一套做法的实现
Observable将关键的方法保护起来
如果你看看Observable APl,你会发现setChanged()方法被保护起来了(被定义成protected)。那又怎么样呢?这意味着:除非你继承自Observable,否则你无法创建Observable实例并组合到你自己的对象中来。这个设计违反了第二个设计原则:“多用组合,少用继承”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值