观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。

观察者模式有四个角色:抽象主题、具体主题、抽象观察者、具体观察者。

ISubject接口(抽象目标):把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。含方法Notify,Register,UnRegister(名字可以自己任意取名)

Subject类(实体目标):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。实现ISubject接口,一般只有一个

IObservable接口(抽象观察者):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

Observer类(实体观察者):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。实现IObservable接口,一般有多个

观察者模式中的“注册--通知--注销”图示:
1. 观察者(Observer)将自己(Regiester)注册到被观察对象(Subject)中,被观察对象将观察者放在一个容器(Container)。Container一般为Ilist,Arraylist等数据结构,存放多个IObservable接口变量。
2.当被观察对象(Subject)发生变化时,容器(Container)中的所有观察者(Observer)都得到通知(Notify 方法),此时观察者会自动执行某些方法。
3.当观察者不想继续观察被观察者时,可以注销(UnRegiester方法)

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

实现代码

抽象观察者(IObservable):

     /// <summary>
/// 只是为了把多个对象产生关系,方便保存和调用
/// 方法本身其实没用
/// </summary>
public interface IObserver
{
void Action();
}

实体观察者(Observer):

     public class Baby : IObserver
{
public void Action()
{
this.Cry();
} public void Cry()
{
Console.WriteLine("{0} Cry", this.GetType().Name);
}
}
     public class Brother : IObserver
{
public void Action()
{
this.Turn();
}
public void Turn()
{
Console.WriteLine("{0} Turn", this.GetType().Name);
}
}
     public class Chicken : IObserver
{
public void Action()
{
this.Woo();
}
public void Woo()
{
Console.WriteLine("{0} Woo", this.GetType().Name);
}
}
     public class Dog : IObserver
{
public void Action()
{
this.Wang();
}
public void Wang()
{
Console.WriteLine("{0} Wang", this.GetType().Name);
}
}
     public class Father : IObserver
{
public void Action()
{
this.Roar();
}
public void Roar()
{
Console.WriteLine("{0} Roar", this.GetType().Name);
}
}
     public class Mother : IObserver
{
public void Action()
{
this.Whisper();
}
public void Whisper()
{
Console.WriteLine("{0} Whisper", this.GetType().Name);
}
}
     public class Mouse : IObserver
{
public void Action()
{
this.Run();
}
public void Run()
{
Console.WriteLine("{0} Run", this.GetType().Name);
}
}
     public class Neighbor : IObserver
{
public void Action()
{
this.Awake();
}
public void Awake()
{
Console.WriteLine("{0} Awake", this.GetType().Name);
}
}
     public class Stealer : IObserver
{
public void Action()
{
this.Hide();
}
public void Hide()
{
Console.WriteLine("{0} Hide", this.GetType().Name);
}
}

实体目标(Subject):

     /// <summary>
/// 一只神奇的猫
///
/// 猫叫一声之后触发
/// baby cry
/// brother turn
/// dog wang
/// father roar
/// mother whisper
/// mouse run
/// neighbor awake
/// stealer hide
///
/// </summary>
public class Cat
{
public void Miao()
{
Console.WriteLine("{0} Miao.....", this.GetType().Name); new Mouse().Run();//依赖
new Chicken().Woo();
new Baby().Cry();
new Brother().Turn();
new Dog().Wang();
new Father().Roar();
new Mother().Whisper();
//new Mouse().Run();
new Neighbor().Awake();
//new Stealer().Hide();
}
//依赖太多,任何一个对象改动,都会导致Cat变化
//违背了单一职责,不仅自己miao 还要触发各种动作,不稳定
//加一个/减一个/调整顺序 Cat都得改 //Cat职责:1 Miao 2 触发一系列动作 这是需求
//实现上,其实多了一个,3 指定动作 //Cat不稳定--这一堆对象--甩锅--自己不写让别人传递
private List<IObserver> _ObserverList = new List<IObserver>();
public void AddObserver(IObserver observer)
{
this._ObserverList.Add(observer);
}
public void MiaoObserver()
{
Console.WriteLine("{0} MiaoObserver.....", this.GetType().Name);
if (this._ObserverList != null && this._ObserverList.Count > )
{
foreach (var item in this._ObserverList)
{
item.Action();
}
}
} public event Action MiaoHandler;
public void MiaoEvent()
{
Console.WriteLine("{0} MiaoEvent.....", this.GetType().Name);
if (this.MiaoHandler != null)
{
foreach (Action item in this.MiaoHandler.GetInvocationList())
{
item.Invoke();
}
}
} }

前端调用:

                 {
Console.WriteLine("***************Common******************");
Cat cat = new Cat();
cat.Miao();
}
{
Console.WriteLine("***************Observer******************");
Cat cat = new Cat();
cat.AddObserver(new Mouse());
cat.AddObserver(new Chicken());
cat.AddObserver(new Baby());
cat.AddObserver(new Brother());
cat.AddObserver(new Dog());
cat.AddObserver(new Father());
cat.AddObserver(new Mother());
cat.AddObserver(new Mouse());
cat.AddObserver(new Neighbor());
cat.AddObserver(new Stealer());
cat.MiaoObserver();
} {
Console.WriteLine("***************Observer******************");
Cat cat = new Cat();
cat.MiaoHandler += new Baby().Cry;
cat.MiaoHandler += new Brother().Turn;
cat.MiaoHandler += new Dog().Wang;
cat.MiaoHandler += new Stealer().Hide;
cat.MiaoHandler += new Neighbor().Awake;
cat.MiaoHandler += new Father().Roar;
cat.MiaoEvent();
}

交互的对象之间应尽量设计成松耦合的

松耦合设计可以让我们设计出这样的系统: 因为对象之间的相互依存减小了, 所以系统可以轻松处理变化

松耦合系统通常是基于消息的系统,此时客户端和远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。只要消息符合协商的架构,则客户端或服务的实现就可以根据需要进行更改,而不必担心会破坏对方

当两个对象是松耦合的时候, 他们可以进行交互, 但是却几乎不了解对方.
观察者模式下的被观察者(Subject)和观察者(Observers)就是松耦合设计的对象. 这是因为:

    • 被观察者(Subject)只知道观察者实现了某个接口

    • 可以随时添加观察者

    • 添加新类型观察者的时候不需要修改被观察者

    • 可以复用观察者或者被观察者

    • 如果被观察者或观察者发生变化了, 那么这些变化不会影响到对方

使用委托的时候, 通常会有两个角色出现: 广播者(被观察者)和订阅者(观察者) [观察者模式]

广播者包含一个委托field, 广播者决定何时广播, 它通过调用委托进行广播.

订阅者就是方法的目标接收者.订阅者可以决定何时开始和结束监听, 是通过在广播者的委托上使用+=和-=操作符来实现的.

订阅者之间互相不了解, 不干扰.

event就是为上述模型所存在的, 它只把上述模型所必须的功能从委托里暴露出来. 它的主要目的就是防止订阅者之间相互干扰.

最简单声明event的方法就是在委托成员前面加上event关键字

本文参考文档:

https://www.runoob.com/design-pattern/observer-pattern.html

https://www.cnblogs.com/abcdwxc/archive/2007/09/19/898856.html

https://www.cnblogs.com/zhiyong-ITNote/p/10970067.html

https://mp.weixin.qq.com/s/XkfiFKPTbOy6kGGzfQOFpA

https://www.jb51.net/article/31665.htm

https://blog.csdn.net/u011966339/article/details/69388534

23种设计模式之观察者模式(Observer Pattern)的更多相关文章

  1. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  2. 实践GoF的23种设计模式:观察者模式

    摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...

  3. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  4. 23种设计模式之观察者模式(Observer)

    观察者模式又称为发布—订阅模式.模型—视图模式.源-监听器模式或从属者(dependents)模式,是一种对象的行为型模式.它定义了对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相 ...

  5. 【Unity与23种设计模式】观察者模式(Observer)

    GoF中定义: "在对象之间定义一个一对多的连接方法,当一个对象变换状态时,其他关联的对象都会自动收到通知." 现实中,社交网络就是个例子. 以前的报社,每次出新刊的时候, 报刊便 ...

  6. [设计模式] 19 观察者模式 Observer Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...

  7. c#设计模式之观察者模式(Observer Pattern)

    场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...

  8. 设计模式之观察者模式(Observer pattern)

    最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下: 上课铃声响起,学生A/B/C/D进入教室:下课铃声响起,学生A/B/C/D离开教室. 要求使用设计模式的思想完成铃与学 ...

  9. 设计模式九: 观察者模式(Observer Pattern)

    简介 观察者属于行为型模式的一种, 又叫发布-订阅模式. 如果一个对象的状态发生改变,依赖他的对象都将发生变化, 那么这种情况就适合使用观察者模式. 它包含两个术语,主题(Subject),观察者(O ...

随机推荐

  1. Spring学习之旅(十一)--JDBC

    JDBC 是数据持久化的一种比较常见的方案,Spring 也对它进行了支持. 在开始 JDBC 的使用之前,我们要先做下一些准备工作. 配置数据源 在 Spring 上下文中可以数据源 Bean 有如 ...

  2. 01_liteide 集成环境运行的问题

    //go语言是以包为管理单位 //每个文件必须先声明包 //程序必须有一个main包 package main import (  "fmt" ) //入口函数 func main ...

  3. ccflow关于流程引擎的父子流程的基本概念

    关键字:驰骋BPM jflow,ccflow, 驰骋工作流引擎 父子流程概念:在管理活动中,通用的部分,公用的部分,可以被重复执行的部分的流程管理活动我们把他独立出来,成为子流程,可以被其他流程的管理 ...

  4. CF980B Marlin 构造 思维 二十四

    Marlin time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  5. 环境变量_JAVA_LAUNCHER_DEBUG,它能给你更多的JVM信息

    关于环境: 本文中的实战都是在docker容器中进行的,容器的出处请参照<在docker上编译openjdk8>一文,里面详细的说明了如何构造镜像和启动容器. 在上一篇文章<修改,编 ...

  6. 试试 IEnumerable 的另外 6 个小例子

    IEnumerable 接口是 C# 开发过程中非常重要的接口,对于其特性和用法的了解是十分必要的.本文将通过6个小例子,来熟悉一下其简单的用法. <!-- more --> 阅读建议 在 ...

  7. 全栈开发博客系统(nodejs+vuejs+mongodb)

    本篇文章将会介绍如何使用nodejs+vuejs构建个人博客. 主要分三部分内容: 环境准备 博客后端管理系统(admin) 后端服务(主要提供admin及web端接口) 博客前端展示(web) 环境 ...

  8. 联邦学习开源框架FATE助力腾讯神盾沙箱,携手打造数据安全合作生态

    近日,微众银行联邦学习FATE开源社区迎来了两位新贡献者——来自腾讯的刘洋及秦姝琦,作为云计算安全领域的专家,两位为FATE构造了新的功能点,并在Github上提交修复了相关漏洞.(Github项目地 ...

  9. Seaborn数据可视化入门

    在本节学习中,我们使用Seaborn作为数据可视化的入门工具 Seaborn的官方网址如下:http://seaborn.pydata.org 一:definition Seaborn is a Py ...

  10. Spring Cloud(二):服务消费者

    创建“服务消费者” 创建一个基础的Spring Boot工程,命名为springboot-consumer,并在pom.xml中引入需要的依赖内容: <dependency> <gr ...