设计模式:观察者模式 和 发布-订阅模式

一、简介

观察者模式是一种使用率很高的模式。这个模式的一个重要作用就是解耦,将被观察者和观察者解耦。在很多地方,都会将观察者模式称为发布-订阅模式,或者订阅者模式。实际上,两者是不完全相同的,有联系也有区别。

二、观察者模式定义

观察者模式,定义了一种一对多的依赖关系,使得当一个对象发生状态变化时,则观察它的对象也都得到通知并作出反应。

三、UML类图

  • 抽象主题(Subject):它把所有观察者对象的引用保存到一个集合中,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以注册和移除观察者。
  • 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
  • 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
  • 具体观察者(ConcreteObserver):实现抽象观察者提供的更新接口,以便本身的状态能够及时更新。

四、观察者模式的实现例子

1、创建一个抽象观察者

public interface Observer {//抽象观察者
        public void update(String message);//更新方法
    }

2、创建具体观察者(以开学为例)

    public class Student implements Observer {

        private String name;
        public Student (String name) {
            this.name = name;
        }
        @Override
        public void termBegins(String message) {
            System.out.println(message + "," + name+"背上书包去学校");
        }
    }

    public class Teacher implements Observer {

        private String name;
        public Teacher (String name) {
            this.name = name;
        }
        @Override
        public void termBegins(String message) {
            System.out.println(message + "," + name+"准备布置新学期学习任务");
        }
    }

3、创建抽象主题

public interface  Observable {
         void add(Observer observer);
 
         void remove(Observer observer);
    
         void notify(String message);
    }

4、创建具体主题

public class School implements  Observable{
        
        private List<Observer> personList = new ArrayList<Observer>();
        @Override
        public void add(Observer observer) {
            personList.add(observer);
        }

        @Override
        public void remove(Observer observer) {
            personList.remove(observer);

        }

        @Override
        public void notify(String message) {
            for (Observer observer : personList) {
                observer.termBegins(message);
            }
        }
    }

5、客户端测试

public void test(){
        Observable school = new School();       
        Observer stu1=new Student("小明");
        Observer teacher1=new Teacher("王老师");

        school.add(stu1);
        school.add(teacher1);       
        school.notify("开学了!");
    }

五、发布-订阅模式

联系

发布-订阅模式是观察者模式的一种变体。发布-订阅只是把一部分功能抽象成一个独立的“中间件”进行转发控制。

区别

1、观察者模式中主体和观察者是互相感知的,发布-订阅模式是借助第三方来实现调度的,发布者和订阅者之间互不感知。

观察者模式比较好理解,发布订阅模式举个栗子,就像报社, 邮局和个人的关系,报纸的订阅和分发是由邮局来完成的。报社只负责将报纸发送给邮局。

2、观察者模式是【一对多】的关系。一触发通知,所有观察者都收到消息。

发布-订阅模式是【多对一】或者【多对多】的关系。

发布-订阅模式适合更复杂的场景,比如只想通知部分订阅者,比如多个发布者发布消息时,通知时机的选择(都发布完再通知还是每发布一个通知一次)。而这些控制的逻辑就是在“中间件”完成的。

六、发布-订阅模式例子

var publisher = {
	publish(pubsub) {
		pubsub.publish()
	}
}
var pubsub = {
	subscribes: [],
	publish() {
		this.subscribes.forEach(subscribe =>{
			subscribe.update();
		})
	},
	subscribe(sub) {
		this.subscribes.push(sub)
	}
}
var subscribe = {
	update() {
		console.log('update')
	},
        subscribe(pubsub) {
            pubsub.subscribe(this);
        }
}
subscribe.subscribe(pubsub)
publisher.publish(pubsub)

感谢-> https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/25

看代码就很容易理解了。转一下java实现也不难,这里就偷个懒了~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KWMax

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值