观察者模式与推拉模型

深入WebRTC客户端架构:拆解一个基于C++和libwebrtc.a的推拉流SDK核心类设计 本文深入解析了基于C++和libwebrtc.a的WebRTC客户端架构设计,重点介绍了推拉流SDK的核心类实现。通过关注点分离、资源生命周期自动化和线程安全的异步模型,构建高性能的实时音视频通信系统。文章详细探讨了线程模型、信令与媒体分离架构、视频处理管道设计等关键技术,并提供了实际应用中的性能调优建议。 阅读详情

作者卡奴达摩

连接:http://blog.youkuaiyun.com/zhengzhb/article/details/7471978


定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

类型:行为类模式

类图:

        在软件系统中经常会有这样的需求:如果一个对象的状态发生改变,某些与它相关的对象也要随之做出相应的变化。比如,我们要设计一个右键菜单的功能,只要在软件的有效区域内点击鼠标右键,就会弹出一个菜单;再比如,我们要设计一个自动部署的功能,就像eclipse开发时,只要修改了文件,eclipse就会自动将修改的文件部署到服务器中。这两个功能有一个相似的地方,那就是一个对象要时刻监听着另一个对象,只要它的状态一发生改变,自己随之要做出相应的行动。其实,能够实现这一点的方案很多,但是,无疑使用观察者模式是一个主流的选择。

观察者模式的结构

在最基础的观察者模式中,包括以下四个角色:

  • 被观察者:从类图中可以看到,类中有一个用来存放观察者对象的Vector容器(之所以使用Vector而不使用List,是因为多线程操作时,Vector在是安全的,而List则是不安全的),这个Vector容器是被观察者类的核心,另外还有三个方法:attach方法是向这个容器中添加观察者对象;detach方法是从容器中移除观察者对象;notify方法是依次调用观察者对象的对应方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
  • 观察者:观察者角色一般是一个接口,它只有一个update方法,在被观察者状态发生变化时,这个方法就会被触发调用。
  • 具体的被观察者:使用这个角色是为了便于扩展,可以在此角色中定义具体的业务逻辑。
  • 具体的观察者:观察者接口的具体实现,在这个角色中,将定义被观察者对象状态发生变化时所要处理的逻辑。

观察者模式代码实现

abstract class Subject {  
    private Vector<Observer> obs = new Vector<Observer>();  
      
    public void addObserver(Observer obs){  
        this.obs.add(obs);  
    }  
    public void delObserver(Observer obs){  
        this.obs.remove(obs);  
    }  
    protected void notifyObserver(){  
        for(Observer o: obs){  
            o.update();  
        }  
    }  
    public abstract void doSomething();  
}  
  
class ConcreteSubject extends Subject {  
    public void doSomething(){  
        System.out.println("被观察者事件反生");  
        this.notifyObserver();  
    }  
}  
interface Observer {  
    public void update();  
}  
class ConcreteObserver1 implements Observer {  
    public void update() {  
        System.out.println("观察者1收到信息,并进行处理。");  
    }  
}  
class ConcreteObserver2 implements Observer {  
    public void update() {  
        System.out.println("观察者2收到信息,并进行处理。");  
    }  
}  
  
public class Client {  
    public static void main(String[] args){  
        Subject sub = new ConcreteSubject();  
        sub.addObserver(new ConcreteObserver1()); //添加观察者1  
        sub.addObserver(new ConcreteObserver2()); //添加观察者2  
        sub.doSomething();  
    }  
}  


运行结果

被观察者事件反生

观察者1收到信息,并进行处理。

观察者2收到信息,并进行处理。

        通过运行结果可以看到,我们只调用了Subject的方法,但同时两个观察者的相关方法都被同时调用了。仔细看一下代码,其实很简单,无非就是在Subject类中关联一下Observer类,并且在doSomething方法中遍历一下Observer的update方法就行了。

观察者模式的优点

        观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。

        观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。

 

总结

       Java语言中,有一个接口Observer,以及它的实现类Observable,对观察者角色常进行了实现。我们可以在jdk的api文档具体查看这两个类的使用方法。

       做过VC++、JavaScript DOM或者AWT开发的朋友都对它们的事件处理感到神奇,了解了观察者模式,就对事件处理机制的原理有了一定的了解了。如果要设计一个事件触发处理机制的功能,使用观察者模式是一个不错的选择,AWT中的事件处理DEM(委派事件模型Delegation Event Model)就是使用观察者模式实现的。


作者:RayChase

连接:http://raychase.iteye.com/blog/1337015


观察者模式,指的是定义一种对象间的一对多的关系,当一个对象的状态发生变化的时候,所有依赖于它的对象都将得到通知并更新自己。


 

现在要说的分歧在这里:

“推”的方式是指,Subject维护一份观察者的列表,每当有更新发生,Subject会把更新消息主动推送到各个Observer去。

“拉”的方式是指,各个Observer维护各自所关心的Subject列表,自行决定在合适的时间去Subject获取相应的更新数据。

 

“推”的好处包括:

1、高效。如果没有更新发生,不会有任何更新消息推送的动作,即每次消息推送都发生在确确实实的更新事件之后,都是有意义的。

2、实时。事件发生后的第一时间即可触发通知操作。

3、可以由Subject确立通知的时间,可以避开一些繁忙时间。

4、可以表达出不同事件发生的先后顺序。

 

“拉”的好处包括:

1、如果观察者众多,Subject来维护订阅者的列表,可能困难,或者臃肿,把订阅关系解脱到Observer去完成。

2、Observer可以不理会它不关心的变更事件,只需要去获取自己感兴趣的事件即可。

3、Observer可以自行决定获取更新事件的时间。

4、拉的形式可以让Subject更好地控制各个Observer每次查询更新的访问权限。

 

----------------------------------------------------------------------------------------------------------------------------------

2012-2-27 补充:

事实上“推”和“拉”可以比较的内容太多了,比如:

客户端通常是不稳定的,服务端是稳定的,如果消息由客户端主动发起去获取,它很容易找到服务端的地址,可以比较容易地做到权限控制(集中在服务端一处),服务端也可以比较容易地跟踪客户端的位置和状态,反之则不行;

互联网页面的访问就是一个最好的“拉”的模式的例子;

通常我们希望把压力分散到各个客户端上去,服务端只做最核心的事情,只提供内容,不管理分发列表;

……

还有一个idea是关于“推”和“拉”结合的形式,例如,服务端只负责通知某一些数据已经准备好,至于是否需要获取和什么时候客户端来获取这些数据,完全由客户端自行确定。


、、、、、、、转者、、、、、、、

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <algorithm>

/**********************************************************************************
最开始使用智能指针实现的,但是发现了一些"问题":
1、智能指针没有复制兼容性原则:指向子类的智能指针不能向指向父类的智能指针赋值/初始化
2、指向基类的智能指针甚至不能用来指向原生的子类对象
除非自己实现转换函数,且转换函数的频繁调用成为必然,但实际上不应该频繁的转换类型

一些注意事项,观察者在自身析构之前,必须向主题取消注册,以免产生不必要的麻烦
***********************************************************************************/
class AbsSubject;				//前向声明

class AbsObserver
{
public:
	virtual void Update(std::string report) = 0;		//推送内容方式,注意 主题与观察者是分离的,不要盲目追求效率而声明参数为引用
	virtual void Updata(AbsSubject *sj) = 0;			//拉取内容方式,想要知道具体主题的具体内容,需自己去取感兴趣的项,此方式需求客户遵守约定,并且不在运行时修改成员变量
	virtual ~AbsObserver(){};
};

class AbsSubject
{
public:
	virtual void RegisterObserver(AbsObserver *ob) = 0;	//由于允许子类自行选取数据结构存储观察者,因此定义为纯虚函数,此外,此处也助于减少行为的继承
	virtual void CancelObserver(AbsObserver *ob) = 0;
	virtual void Notify() = 0;
	virtual ~AbsSubject(){};							//AbsSubject的子类中可能拥有指向观察者的指针,但不应该在析构函数中释放这些指针,毕竟主题与观察者是独立的
};

class Secretary : public AbsSubject		//专用秘书,单人使用
{
private:
	AbsObserver *pLeader;
	std::string plan;

	void Notify()
	{
		if( NULL != pLeader )
		{
			pLeader->Update(plan);
		}
	}

public:
	Secretary() : pLeader(NULL)
	{	
	}
	explicit Secretary(AbsObserver *ob)
	{
		RegisterObserver(std::move(ob));		
	}
	void RegisterObserver(AbsObserver *ob)
	{
		pLeader = ob;
	}
	void CancelObserver(AbsObserver *ob)
	{
		pLeader = NULL;
	}
	void SetPlan(std::string NewPlan)	
	{
		plan = NewPlan;
		Notify();
	}
};

class Reception : public AbsSubject		//勤劳的前台MM
{
private:
	std::vector<AbsObserver *> member;
	std::string bossEvent;
	std::string managerEvent;
	std::string HREvent;

public:
	Reception()
	{
	}
	explicit Reception(AbsObserver *ob)
	{
		RegisterObserver(ob);
	}
	void RegisterObserver(AbsObserver *ob)
	{
		member.push_back(std::move(ob));		//避免拷贝
	}
	void CancelObserver(AbsObserver *ob)
	{
		std::vector<AbsObserver *>::const_iterator it;
		it = std::find(member.cbegin(), member.cend(), ob);
		if( it != member.cend() )
		{
			member.erase(it);
		}
	}
	void Notify()
	{
		for (auto &it : member)
		{
			if( NULL != it )
			{
				it->Updata(this);
			}
		}
	}
	void HasEvent(std::string bossEvent, std::string managerEvent, std::string HREvent)
	{
		this->bossEvent = bossEvent;
		this->managerEvent = managerEvent;
		this->HREvent = HREvent;
		Notify();
	}
	std::string GetBossEvent()const
	{
		return bossEvent;
	}
	std::string GetMnagerEvent()const
	{
		return managerEvent;
	}
	std::string GetHREvent()const
	{
		return HREvent;
	}
};

class Boss : public  AbsObserver			
{
private:
	std::string plan;
public:
	void Update(std::string report)								//推送数据,推送方式下观察者不能选择性获取自己感兴趣的内容
	{
		plan = report;
		std::cout << "Boss " << report << std::endl;
	}
	void Updata(AbsSubject * sj)									//拉取数据,此方式可由观察者选择自己感兴趣的内容
	{
		if(  Reception * re = dynamic_cast<Reception *>(sj) )
		{			
			std::cout << "Boss " << re->GetBossEvent() << std::endl;		//挑自己感兴趣的
		}
	}
};

class Manager : public AbsObserver			
{
public:
	void Update(std::string report)
	{
		std::cout << report << std::endl;
	}
	void Updata(AbsSubject * sj)
	{
		if (Reception * re = dynamic_cast<Reception *>(sj))
		{
			std::cout << "Manager " << re->GetMnagerEvent() << std::endl;
		}
	}
	void DoSomething()
	{
		std::cout << "DoSomething" << std::endl;
	}
};

class HR : public AbsObserver					
{
public:
	void Update(std::string report)
	{
		std::cout << report << std::endl;
	}
	void Updata(AbsSubject * sj)
	{
		if( Reception * re = dynamic_cast<Reception *>(sj) )
		{
			std::cout << "HR " <<re->GetHREvent() << std::endl;
		}
	}
	void DoSomething()
	{
		std::cout << "DoSomething" << std::endl;
	}
};

int main(int argc, char **argv)
{
	Boss boss;
	Secretary secretary(&boss);
	Reception *reception = new Reception;
	if( NULL == reception )
		return -1;

	Manager manager;
	HR *hr = new HR;
	if( NULL == hr )
		return -1;

	reception->RegisterObserver(&manager);
	reception->RegisterObserver(hr);
	reception->RegisterObserver(&boss);

	hr->DoSomething();

	secretary.SetPlan(std::string("phone call"));
	reception->HasEvent(std::string("visit"), std::string("expressage"), std::string("interview"));

	manager.DoSomething();

	secretary.CancelObserver(&boss);
	reception->CancelObserver(hr);
	reception->CancelObserver(&manager);
	reception->CancelObserver(&boss);
	
	secretary.SetPlan(std::string("nothing"));
	reception->HasEvent(std::string("nothing"), std::string("nothing"), std::string("nothing"));

	delete reception;
	delete hr;

	return 0;
}





【C++实战㊻】解锁C++观察者模式:从理论到实战 本文是 C++ 实战专栏第 46 篇,聚焦观察者模式。先阐述其概念,包括 “一对多依赖,状态变则通知依赖对象” 的定义,事件监听等适用场景,以及主题、观察者接口、具体观察者的结构;再讲解实战应用,含实现代码、推 / 拉模型区别与线程安全处理;还分享解耦设计等实战技巧;最后通过股票行情通知系统实战,展示需求分析、模式实现与多客户端并发测试,助力读者掌握该模式在 C++ 中的应用。 阅读详情

相关推荐

浅谈专项测试之弱网络测试

浅谈专项测试之弱网络测试 一.弱网络测试背景 移动端产品的使用并非完全都是在流畅的wifi环境,大部分用户主要使用4G,3G,2G等网络,另外因为移动端产品使用的场景多变,如进公交,上地铁,坐电梯,使得弱网测试显得尤为重要。考虑到各种场景的客户端展示及容错,提升产品的印象和用户体验,提高产品的健壮性,弱网测试必不可少。 二.弱网络测试建议 网下需要进行功能点测试,无网络测试,网络切换测试等,测试过程除了关注功能点的实现,还应关注用户体验等各个方面 三.弱网络测试通用功能点总结 四.弱网络测试用例实例

ITstudy001的博客 1011

观察者模式:推模型与拉模型

简介 在观察者模式中,又分为推模型和拉模型两种方式。   ●  推模型      主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。   ●  拉模型      主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过u

public 6184

从零开始利用MATLAB进行FPGA设计(一):建立脉冲检测模型的Simulink模型2

上一期分析了MATLAB的黄金算法原理,这一期进行Simulink模块分析。

WZT725的博客 2086

设计模式学习(八):观察者模式-1(拉模式)

2019年4月10日 概念 观察者模式: 在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。(其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。) 应用场景:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。 推(push)模式是一种基于客户器/服务器机制...

Diligence is the mother of success. 565

新手工程师必看:搞定EMI传导干扰,从理解差模和共模开始(附实战案例)

本文深入解析EMI传导干扰中的差模与共模问题,为新手工程师提供从诊断到治理的完整方法论。通过实战案例展示如何通过频谱分析、近场探头扫描等技术精准定位干扰源,并分享PCB布局、滤波器设计等系统级解决方案,帮助工程师高效解决传导干扰问题,提升EMC设计能力。

weixin_26757925的博客 472

Ubuntu终端AI编程助手配置:Claude Code接入DeepSeek模型全攻略

在软件开发领域,AI编程助手正成为提升开发效率的重要工具。其核心原理是通过大语言模型理解自然语言指令,生成、解释或调试代码。这类工具的技术价值在于将AI能力无缝集成到开发工作流中,减少上下文切换,实现更流畅的人机协作。常见的应用场景包括代码生成、错误调试、代码重构和技术问答等。本文聚焦于在Ubuntu系统中,将流行的终端AI助手Claude Code的后端模型从原版Claude替换为DeepSeek。通过配置环境变量实现API端点和模型的映射,这一过程涉及Node.js环境管理、npm包安装和关键环境变量设

weixin_42527654的博客 378

观察者模式

观察者模式又名发布-订阅模式,定义了对象之间的一对多依赖,多个对象同时监听一个对象,当被监听对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新,被监听对象称为主题,监听对象称为观察者。

lansuiyun的专栏 2368

【机器人】线性方程最小二乘解法对机械臂DH参数进行标定

1.前言 看了一篇文章,觉得里面的DH参数标定法讲的很清晰,便使用Matlab复现了一下,效果还可以,特写此文记录。 2.原理 2.1.误差最佳值的最小二乘计算 有研究结果表明:几乎95%的机器人位置误差都是由机器人内部运动学的不准确描述引起的,所以对DH模型参数进行标定是很有必要的。 DH参数物理含义:选自《机器人学、机器视觉与控制-Matlab基础》 当DH参数确定后,我们...

要恰饭得嘛 1万+

观察者模式中,消息采用推和拉方式来传递的比较

观察者模式,指的是定义一种对象间的一对多的关系,当一个对象的状态发生变化的时候,所有依赖于它的对象都将得到通知并更新自己。   现在要说的分歧在这里: “推”的方式是指,Subject维护一份观察者的列表,每当有更新发生,Subject会把更新消息主动推送到各个Observer去。 “拉”的方式是指,各个Observer维护各自所关心的Subject列表,自行决定在合适的时间去Subj...

四火专栏 738

基于Python的网贷平台数据爬虫实战:Scrapy+Selenium+反反爬策略

python复制下载# items.py本文详细介绍了如何使用Python构建一个完整的网贷平台数据爬虫系统,涵盖了从基础爬取到高级反反爬策略的全套解决方案。我们使用了Scrapy框架作为基础,结合Selenium处理动态内容,实现了多种反反爬策略,并探讨了分布式爬虫的实现方式。机器学习识别验证码基于深度学习的网页结构变化检测自动化行为模拟的更精细控制基于Kubernetes的弹性爬虫集群。

2201_76125261的博客 1560

【学习系列】SAP RAP 2:创建第一个RAP应用

本文介绍了从零开始创建基于SAP RAP(ABAP RESTful Application Programming Model)的Fiori应用的完整流程。首先说明了学习RAP需要结合官方文档和教程,并提供了相关资源链接。文章详细讲解了开发环境的准备要求,包括系统版本、开发工具和基本知识。重点演示了如何通过8个步骤创建支持CRUD操作和草稿功能的RAP应用:1)创建数据库表;2)定义CDS视图实体;3)创建投影视图;4)定义行为;5)创建行为投影;6)定义服务;7)绑定服务;8)添加UI注解。

DeveloperMrMeng的博客 1499

设计模式——观察者模式

定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变是,所有依赖于它的对象都能得到通知并被自动更新 场景: 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面 当对一个对象的改变需要同时桶盖其他对象,而不知道具体有多少个待改变对象 当一个对象必须通知其他对象,而它又不能假设其他对象是谁 类图: 图片来自《设计模式之禅》 ​​​​优点: 降低主题和观察者之间的耦合 支持...

afterlake的博客 169

【第三方互联】3、腾讯QQ授权第三方登录

当我们创建的 QQ 互联应用成功后,我们便可以开始使用该应用来实现 QQ 互联 一、获取 APP ID 和 APP Key 1、找到我的应用 2、点击应用,进入详情 这样,我们就获取到了 APP ID 和 APP Key 二、进行开发 1、将 APP ID 、APP Key,以及该应用的信息放入项目中的配置文件中,我使用的是SpringBoot,我放在了 application.y...

JACKAL 22万+

Java设计模式の观察者模式(推拉模型)

目录:   一.观察者定义  二.观察者模式的结构(推模式实现)  三.推模型和拉模型(拉模式实现)  四.JAVA提供的对观察者模式的支持  五.使用JAVA对观察者模式的支持(自带推模式实现实例) 一.观察者定义 在阎宏博士的《JAVA与模式》一书中开头是这样描述观察者(Observer)模式的:   观察者模式是对象的行为模式,又叫发布-订阅(Publ...

weixin_30699443的博客 274

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

大话设计模式——观察者模式(二)

前言:基础的观察者模式:大话设计模式——观察者模式(一)一、再识观察者模式1.1 目标与观察者目标与观察者的关系是典型的一对多关系,当然,实现一对一也是可以的。 一个观察者,可以关注多个目标,一个目标也可以被多个观察者观察。 比如,小陈的女朋友和他老妈可以同时关注天气信息。而小陈的女朋友也可以同时关注天气和报纸。需要注意的是,这时的通知方法要进行区分。1.2 单向依赖观察者依赖目标。主动权在目标

Charon1997的博客 471

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

设计模式之观察者模式

在慕课网上学习了观察者模式,故做个笔记温习巩固一下http://www.imooc.com/learn/415 经典观察者模式 Java自带的观察者模式 区别对待的观察者模式

学习笔记 3011

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

观察者模式(Observer) Java实现

观察者模式 观察者模式(Observer)的定义 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。 观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能...

CmdSmith的博客 7323

状态发生改变时通知观察者——观察者模式

观察者模式 一、概述 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 二、观察者模式的结构 一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样...

在路上 1070

设计模式之旅—观察者模式

观察者模式分析思路介绍: 观察者模式介绍 观察者模式实战 观察者模式详解 观察者模式衍生 一、观察者模式介绍 定义: 定义对象间一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 案例场景描述: 小明是天气预报部门的员工能获取最新的天气环境的数据,所以他的女朋友和老妈可以及时的了解到相关天气信息,从而合理的安排她们各自出行的相关行程,这...

紫梦小缘 317

观察者模式(Observer)

一、定义 定义对象见的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式的角色: 抽象主题角色(Subject):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。 具体主题角色(ConcreteSubject):在具体主题内...

wuychn 223

『多媒体』流媒体之 工作模型

1. 网络中的推拉模式 信息推拉模式 信息推拉技术是将信息推送与拉取两种模式结合,因而能做到取长补短,使二 者优势互补。根据推、拉结合顺序及结合方式的差异,又分以下四种不同推拉 模式: 先推后拉——先由信源及时推送公共信息,再由用户有针对性地拉取个性化信 息;  先拉后推——根据用户拉取的信息,信源进一步主动提供(推送)与之相关的

fallenink的专栏 1238

java-设计模式-观察者模式

简单观察者模式 观察者模式中,一个被观察者管理所有依赖它的观察者,并且在本身的状态改变时主动发出通知。这通常通过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。 角色 抽象被观察者角色:把所有对观察者对象的引用保存在一个集合中,每个被观察者角色都可以有任意数量的观察者。被观察者提供一个接口,可以增...

weixin_34082177的博客 82

**观察者模式(Observer Pattern)**,一种行为型设计模式,也被称为“发布-订阅模式(Publish-Subscribe)”的简化版

- “Pub/Sub 是观察者模式的升级版” —— 不准确。二者目标一致(解耦通知),但**解决的问题域不同**:Observer 解决**单进程内对象协作**,Pub/Sub 解决**系统级松散集成**。 - 很多前端库(如 Vue 的 `EventBus`、RxJS 的 `Subject`)虽名含 “Subject”,实为模拟 Pub/Sub 的轻量中介,已脱离经典 Observer 的直连结构。 -

[Blog][Domain] programb.blog.youkuaiyun.com 609
上一篇: 23种设计模式(1):单例模式
下一篇: 策略模式
早起的虫儿灬
博客等级 码龄10年 54粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值