美文网首页
观察者模式

观察者模式

作者: nieniemin | 来源:发表于2020-06-22 22:52 被阅读0次

什么是观察者模式

定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,时他们能够自动更新自己。

模式角色

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

UML类图

观察者模式

代码实现

以微博明星为例可以很好解释观察者定义。每个明星(Star)都会有很多粉丝(几十万、几百万、上千万粉丝关注)。粉丝关注着明星的一举一动(粉丝群it是抽象观察者角色),每当明星更新动态那些粉丝就会立马收到消息,点赞的,评论的,控评的,骂人的等等。这里明星Star很明显就是个抽象主题角色,最近很火的明星罗志祥就是具体主题角色的一员。罗志祥发微博上热门后,吃瓜群众会跟风,为后续继续吃瓜关注罗志祥,这就是增加观察者对象,粉丝对罗志祥失望要脱粉,这就是减少观察者对象。粉丝收到通知后点赞,评论这就是在更新了。下面用代码来具体的描述下观察者模式:

public interface Star {

    void  addFan(Fan fan);
    void deleteFan(Fan fan);

    void notifyFans(String msg);
}
public class LuoZhiXiang implements Star {

    private List<Fan> fanList = new ArrayList<>();
    private String starName;

    public LuoZhiXiang(String starName) {
        this.starName = starName;
    }

    @Override
    public void addFan(Fan fan) {
        fanList.add(fan);
    }

    @Override
    public void deleteFan(Fan fan) {
        fanList.remove(fan);
    }

    /**
     * 在具体主题内部状态改变时,给所有登记过的观察者发出通知.
     * @param msg
     */
    @Override
    public void notifyFans(String msg) {
        fanList.forEach(x -> x.update(msg, starName));
    }

}
public interface Fan {

    void update(String msg, String starName);
}
public class ConcreteFanA implements Fan {
    private String fanName;

    public ConcreteFanA(String fanName) {
        this.fanName = fanName;
    }


    @Override
    public void update(String msg, String starName) {
        System.out.println(fanName + "收到了" + starName + "的微博" + msg);
    }
}
public class ConcreteFanB implements Fan {
    private String fanName;

    public ConcreteFanB(String fanName) {
        this.fanName = fanName;
    }

  // 这个粉丝对idol很失望,说了些不好的言论。罗志祥把他拉黑了。
    @Override
    public void update(String msg, String starName) {
        System.out.println(fanName + "收到了" + starName + "的微博" + msg +"后,评价了罗志祥微博。");
    }
}
public class Client {

    public static void main(String[] args) {
        Fan fanA = new ConcreteFanA("张三");
        Fan fanB = new ConcreteFanB("李四");
        Star showLo = new LuoZhiXiang( "罗志祥");
        showLo.addFan(fanA);
        showLo.addFan(fanB);

        showLo.notifyFans("道歉小作文");
        //  罗志祥就把他拉黑了。
        showLo.deleteFan(fanB);
      // 被拉黑粉丝,就没办法再实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
        showLo.notifyFans("道歉小作文2");
    }
}

张三收到了罗志祥的微博道歉小作文
李四收到了罗志祥的微博道歉小作文后,评价了罗志祥微博。
张三收到了罗志祥的微博道歉小作文2

优点

  • 观察者模式在被观察者和观察者之间建立一个抽象的耦合。主题角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。
  • 观察者模式满足“开-闭原则”。主题接口仅仅依赖于观察者接口,这样,就可以让创建具体主题的类也仅仅是依赖于观察者接口,因此,如果增加新的实现观察者接口的类,不必修改创建具体主题的类的代码。。同样,创建具体观察者的类仅仅依赖于主题接口,如果增加新的实现主题接口的类,也不必修改创建具体观察者类的代码。

缺点

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。
  • 如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
    观察者模式完整代码

相关文章

  • 11.9设计模式-观察者模式-详解

    设计模式-观察者模式 观察者模式详解 观察者模式在android中的实际运用 1.观察者模式详解 2.观察者模式在...

  • RxJava基础—观察者模式

    设计模式-观察者模式 观察者模式:观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式...

  • 前端面试考点之手写系列

    1、观察者模式 观察者模式(基于发布订阅模式) 有观察者,也有被观察者。 观察者需要放到被观察者列表中,被观察者的...

  • RxJava 原理篇

    一、框架思想 观察者模式观察者自下而上注入被观察者被观察者自上而下发射事件观察者模式 装饰器模式自上而下,被观察者...

  • 观察者模式

    观察者模式概念 观察者模式是对象的行为模式,又叫作发布-订阅(publish/subscrible)模式。 观察者...

  • 设计模式-观察者模式

    观察者模式介绍 观察者模式定义 观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为...

  • 观察者模式

    观察者模式 观察者模式的定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/s...

  • iOS设计模式之观察者模式

    观察者模式 1、什么是观察者模式 观察者模式有时又被称为发布(publish)-订阅(Subscribe)模式、模...

  • 观察者模式和发布订阅模式区别

    观察者模式 所谓观察者模式,其实就是为了实现松耦合(loosely coupled)。 在观察者模式中,观察者需要...

  • RxJava(二)

    一、观察者模式 1.1、传统的观察者模式 1.2、RxJava 的观察者模式 区别传统的观察者模式是一个 Obse...

网友评论

      本文标题:观察者模式

      本文链接:https://www.haomeiwen.com/subject/telatktx.html