15.观察者模式&发布/订阅模式

15.观察者模式&发布/订阅模式

1. 观察者模式

1.概念&优缺点

  1. 概念

    观察者模式:
       1. 在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
       2. 其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
       3. 抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
     抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
     具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
     具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
       4. 有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。
    
  2. 优点

    1. 低耦合
  3. 缺点

    1. 观察者与主题绑定,仍有一定耦合性

2.类图

类图

3.代码

Observer.java

package com.desmond.codebase.designpattern.observer;

/**
 * Created by presleyli on 2018/6/14.
 */
public interface Observer {
    void update(String message);
}

Observerable.java

package com.desmond.codebase.designpattern.observer;

/**
 * Created by presleyli on 2018/6/14.
 */
public interface Observerable {
    void registerObserver(Observer o);

    void removeObserver(Observer o);

    void notifyObserver();

}

User.java:

package com.desmond.codebase.designpattern.observer;

import java.text.MessageFormat;

/**
 * Created by presleyli on 2018/6/14.
 */
public class User implements Observer {

    private String name;
    private String message;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        this.message = message;

        read();
    }

    public void read() {
        System.out.println(MessageFormat.format("{0} received {1}", name, message));
    }
}

WechatServer:

package com.desmond.codebase.designpattern.observer;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by presleyli on 2018/6/14.
 */
public class WechatServer implements Observerable {

    private List<Observer> list;
    private String message;

    public WechatServer() {
        this.list = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty()) {
            list.remove(o);
        }
    }

    @Override
    public void notifyObserver() {
        Iterator<Observer> iterable = list.iterator();

        while (iterable.hasNext()) {
            iterable.next().update(message);
        }
    }

    public void setInformation(String s) {
        this.message = s;

        System.out.println(MessageFormat.format("wechat server is updating message: {0}", s));

        notifyObserver();
    }
}

Test:

package com.desmond.codebase.designpattern.observer;

/**
 * Created by presleyli on 2018/6/14.
 */
public class Test {
    public static void main(String[] args) {
        WechatServer server = new WechatServer();

        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");

        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInformation("PHP是世界上最好用的语言!");

        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInformation("JAVA是世界上最好用的语言!");

    }
}

Output:

wechat server is updating message: PHP是世界上最好用的语言!
ZhangSan received PHP是世界上最好用的语言!
LiSi received PHP是世界上最好用的语言!
WangWu received PHP是世界上最好用的语言!
----------------------------------------------
wechat server is updating message: JAVA是世界上最好用的语言!
LiSi received JAVA是世界上最好用的语言!
WangWu received JAVA是世界上最好用的语言!

Process finished with exit code 0

2.发布-订阅模式

1.概念

概念与观察者很类似,但是最大的区别 发布者和订阅者彼此不知道对方的存在,它们依赖一个第三方的中介者进行串联 , 如何进行消息过滤?最流行的方式是基于***主体***以及***内容***[维基百科][https://en.wikipedia.org/wiki/Publish–subscribe_pattern#Message_filtering]

发布订阅

2. 两个模式最重要的区别

区别

3. 差异总结

  1. 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录,然而,在发布-订阅模式中,发布者和订阅者不知道对方的存在,它们只有通过消息代理进行通信, 这样也可以做到真正解耦,发布者和订阅者可以是完全不同的服务(不同语言,不同工作模式等等),只要遵循一套数据格式即可。
  2. 在发布-订阅模式中,组件是松耦合的,这点与观察者模式相反
  3. 观察者模式大多是同步的,比如事件触发,Subject就会去调用观察者的方法。而发布-订阅模式,大多是异步的,比如消息队列。
  4. 观察者模式需要在单个应用传给你下地址空间实现,而发布-订阅模式更像交叉应用模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值