设计模式深入学习--Observer 观察者模式(行为型模式)

常见行为型:观察者模式Observer 例子:基于同一组数据,生成了很多不同的界面来显示,有曲线图显示方式,有圆饼图显示方式,有柱状图显示方式等等…,当底层数据发生改变时,所有基于同一组数据的图像显示都需要修改图像,那么此时有两种实现方式所有图形界面模块都去观察底层数据是否做了改变,如果变化,那么读取数据,修改图像显示。 阅读详情

   今天我们继续来聊聊Observer 观察者模式 。Observer 观察者模式是新手入门通知类编程解耦合的最佳设计模式,没有之一。观察者模式有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。先来看基本使用用法。

   

/// <summary>
/// Subject类 主题抽象统治者
/// </summary>
abstract class Subject
{
    private List<object> observers=new List<object>();
 
    //增加观察者
    public void Attack(Observer observer)
    {
        observers.Add(observer);
    }
    //移除观察者
    public void Detach(Observer observer)
    {
        observers.Remove(observer);
    }
 
    //通知
    public void Notify()
    {
        foreach (Observer o in observers)
        {
            o.Update();
        }
    }
 
}
 
/// <summary>
/// Observer类 抽象观察者 为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口,抽象观察者一般用一个抽象类或者一个接口实现。
/// 更新接口通常包含一个Update()方法
/// </summary>
abstract class Observer
{
    public abstract void Update();
 
}
 
 
/// <summary>
/// 具体主题或具体通知者,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知
/// </summary>
class ConcreteSubject : Subject
{
    private string subjectState;
    //具体被观察者状态
    public string SubjectState
    {
        get { return subjectState; }
        set { subjectState = value; }
    }
}
 
/// <summary>
/// 具体观察者。实现抽象观察者角色需要的更新接口,以便使本身的状态与主题的状态相协调,保存一个指向具体主题对象的引用,
/// 具体观察者角色通常用一个具体子类实现
/// </summary>
class ConcreteObserver : Observer
{
    private string name;
    private string observerState;
    private ConcreteSubject subject;
 
    public ConcreteObserver(ConcreteSubject subject, string name)
    {
        this.subject = subject;
        this.name = name;
    }
 
    public override void Update()
    {
        observerState = subject.SubjectState;
        Console.WriteLine("观察者:"+name+"的新状态是:"+observerState);
    }
 
    public ConcreteSubject Subject
    {
        get { return subject; }
        set { subject = value; }
    }
}

   首先定义两个抽象类 ,Subject通知者类 它包含一个抽象类Observer 列表还有3个方法,添加观察者,移除观察者,和通知观察者方法。一个 抽象Observer观察者类 它包含了一个一个方法Update()  用来给通知者执行该方法。 
   接下来是 具体通知者ConcreteSubject类,声明一个string 用来表面自己的名字。还有具体观察者ConcreteObserver类,里面声明一个string名字和一个string状态,一个通知者类。 然后在初始化方法里面把具体通知者传入的类和名字保存到自身引用内。重写了父类的Update() 方法。输出存放的通知者名称和状态。这样我们的通知者就可以通知观察者了。最后再来写我们的运行过程:

ConcreteSubject s=new ConcreteSubject();
         s.Attack(new ConcreteObserver(s,"X"));
         s.Attack(new ConcreteObserver(s, "Y"));
         s.Attack(new ConcreteObserver(s, "Z"));
 
         s.SubjectState = "ABC";
         s.Notify();
         s.SubjectState = "D";
         s.Notify();
         Console.Read();
   首先声明一个具体通知者ConcreteSubject,在添加方法内new 添加3个观察者,分别是xyz。然后声明新状态ABC,然后下发通知,再改变状态为D,再下发通知。
 

   我们就可以看到3个观察者xyz分别输出了两次状态。
   我们再来做个小例子,可以更好的理解观察者模式的应用场景,比如我们在游戏中,像Boss重生,就会通知战场的全部玩家,又或者游戏中的补给包降落在战场,我们全部玩家都会收到信息,大量相同的消息分发给大量的人,就可以使用这样的 观察者模式,先来试试:

//通知者接口
  interface ISubjects
  {
      void Attach(Observers o);
      void Detach(Observers o);
      void Notify();
 
      string SubjectState { get; set; }
  }
  //观察者
  abstract class Observers
  {
      protected string name;
      protected ISubjects sub;
 
      public Observers(string name, ISubjects sub)
      {
          this.name = name;
          this.sub = sub;
      }
 
      public abstract void identifyDanger();
      public abstract void identifySupy();
  }
 
  //具体通知者Boss
  class Boss : ISubjects
  {
      //需要通知的列表
      private List<Observers> observers=new List<Observers>();
      private string action;
 
      //增加
      public void Attach(Observers o)
      {
          observers.Add(o);
      }
      //减少
      public void Detach(Observers o)
      {
          observers.Remove(o);
      }
 
      public void Notify()
      {
          foreach (Observers o in observers)
          {
              o.identifyDanger();
          }
      }
 
      public string SubjectState
      {
          get { return action; }
          set { action = value; }
      }
  }
  
  //具体通知者补给箱
  class SupplyBox : ISubjects
  {
      //需要通知的列表
      private List<Observers> observers = new List<Observers>();
      private string action;
 
      //增加
      public void Attach(Observers o)
      {
          observers.Add(o);
      }
      //减少
      public void Detach(Observers o)
      {
          observers.Remove(o);
      }
 
      public void Notify()
      {
          foreach (Observers o in observers)
          {
              o.identifySupy();
          }
      }
 
      public string SubjectState
      {
          get { return action; }
          set { action = value; }
      }
  }
 
 
  //具体观察者 
  class NPCPlayer : Observers
  {
      public NPCPlayer(string name, ISubjects sub)
          : base(name, sub)
      {
 
      }
 
 
      public override void identifyDanger()
      {
          Console.WriteLine(sub.SubjectState + " " + name + " 收到," + "组建玩家准备攻击");
      }
 
      public override void identifySupy()
      {
          Console.WriteLine(sub.SubjectState + " " + name + " 收到," + "开始前往占领");
      }
  }
 
  //具体观察者 
  class EnemyPlayer : Observers
  {
      public EnemyPlayer(string name, ISubjects sub)
          : base(name, sub)
      {
 
      }
 
 
      public override void identifyDanger()
      {
          Console.WriteLine(sub.SubjectState + " " + name + " 收到," + "联合Boss一起攻击玩家");
      }
 
      public override void identifySupy()
      {
          Console.WriteLine(sub.SubjectState+" " + name + " 收到," + "开始前往争抢");
      }
  }
 
 
  //具体观察者 
  class Player : Observers
  {
      public Player(string name, ISubjects sub)
          : base(name, sub)
      {
 
      }
 
 
      public override void identifyDanger()
      {
          Console.WriteLine(sub.SubjectState + " " + name + " 收到," + "Boss产生了");
      }
 
      public override void identifySupy()
      {
          Console.WriteLine(sub.SubjectState + " " + name + " 收到," + "地图上出现补给了");
      }
  }
   我们在代码中,首先声明虚拟的通知者类ISubjects和观察者类Observers。 然后是两个具体通知者,一个就是我们说的Boss 和一个补给箱。他们方法类似,都是添加删除和通知,但是这里不一样的地方是 boss调用的是观察者类的identifyDanger()而补给箱调用的是identifySupy() 用来区分开来,实际的游戏可以改进成传入一个Model类,观察者去解包Model类执行。这样通知者的发消息接口就统一起来了。然后我们这里分别做了3个观察者,一个是npc,代表友军,一个enemy 代表敌人,还有一个player代表自己。最后看看运行的代码。
  首先声明一个Boss通知者,在new3个观察者,把boss传入。boss通知者把玩家挨个添加起来,然后声明消息内容,通知。补给包代码也类似,我们就可以看到效果了:
   
   效果是不是吊炸天呢,这样在游戏中我们首先初始化一个通知者,然后做一个列表把观察者挨个存入,当新new一个通知者的时候就把需要通知的观察者传入,最后通知者一句代码,就可以让全部观察者收到消息。大型项目一般就是消息满天飞,其中不乏就有很多这样的内部消息通知,不过这只是一个简单的示例,实际上
观察者还可以配合其他模式一起用,如PureMvc就是外观+观察者模式+其他模式组成的MVC架构。该设计模式还有许多可以深入的东西,以后慢慢挖掘。结尾再来总结下-Observer 观察者模式的优缺点
  优点:观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。

  缺点:依赖关系并未完全解除,抽象通知者依旧依赖抽象的观察者。

  适用场景:
  当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。
  一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。


设计模式——学习笔记——观察者模式Observer——基础篇 Observer(观察者模式)是一个非常有意思的模式,在实际应用中非常的广泛,诸如时间监听模型,Tomcat中对组件生命周期的控制。同时Observer模式在一些场景下会与其他模式配合使用,如Adapter(适配器模式)、Strategy(策略模式)等。 由于Observer的使用非常的灵活,并鉴于本人目前的水平,简要的从以下几个方面介绍Observer: Observer的含义O 阅读详情

相关推荐

100个Python代码大全:学完这篇从Python小白到架构师

Python是一种广泛使用的高级编程语言,以其简洁优雅、易于学习和强大的库而闻名。无论你是一位经验丰富的程序员还是初学者,都可以从这种语言的丰富资源中受益。在本篇博客中,我将分享100个实用的Python代码示例,旨在帮助你掌握Python编程,并在日常工作中提高效率。

penggerhe的博客 1万+

设计模式学习之观察者模式(Observer,行为型模式)(7)

1.观察者模式又叫做发布-订阅模式。 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 3.使用观察者模式的好处:维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。什么时候使用观察者模式:当一个对象的改变需要同时改变其他对象的时候...

weixin_33826609的博客 62

一文读懂无人机AI识别算法,原理、技术、应用

本文详细介绍了无人机识别算法的工作原理、技术优势以及在多个行业的应用前景,展现了其在提升安全监控、资源管理和应急响应中的关键作用。尽管无人机识别算法在多个领域展现出巨大潜力,但仍面临技术挑战,如算法的准确性、数据的实时处理能力以及对复杂环境的适应性。4. 消防与城市管理: 无人机识别算法在消防和城市管理中的应用,为相关部门提供了及时的信息支持,提升了应急处置能力和城市管理水平。1. 公安监控: 无人机识别算法在公安领域的应用,可以实时识别犯罪嫌疑人和违法行为,有效提升城市治安管理的智能化水平。

foiadrone的博客 1849

C#面向对象设计模式纵横谈 学习笔记19 Observer观察者模式(行为型模式)

  意图       定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。动机在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系"。一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好的抵御变化。使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关

Lawrence的专栏 1500

【AUCell打分】:评估一个基因集在单细胞转录组的每个细胞中特定的活性程度

AUCell使用曲线下面积来计算输入基因集的一个有意义的基因子集是否在每个细胞的表达基因中富集。AUC 分数在所有细胞中的分布允许探索特征的相对表达。由于评分方法是基于排名的,因此 AUCell 与基因表达单位和归一化程序无关。此外,由于细胞是单独评估的,因此可以很容易地应用于更大的数据集。

weixin_40695088的博客 1万+

49、非合作目标运动参数估计与状态滤波方法研究

本文研究了非合作空间目标的运动参数估计与状态滤波方法。通过分析目标的章动运动特性,建立了运动方程,并分别提出了基于最小二乘法的质心运动参数估计方法和旋转运动参数估计方法。同时,设计了误差状态卡尔曼滤波器(ESKF)用于姿态滤波和角速度估计,以提高估计精度。仿真实验验证了所提方法的有效性,能够准确估计目标的运动参数和状态信息,为在轨服务提供了技术支持。

gpt4scribbler的博客 89

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

大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章将23种设计模式中的观察者模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

PyTorch深度学习实战(3)——使用PyTorch构建神经网络

PyTorch 是一个用于构建深度神经网络的库,具有灵活性和可扩展性,可以轻松自定义模型。在本节中,我们将使用 PyTorch 库构建神经网络,利用张量对象操作和梯度值计算更新网络权重,并利用 Sequential 类简化网络构建过程,最后还介绍了如何使用 save、load 方法保存和加载模型,以节省模型训练时间。

盼小辉丶的博客 8万+

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

引言 观察者模式可以说是JDK中使用最多的模式之一,这个模式可以让你的对象随时随地的了解想要知道的情况,你还可以让某个对象在运行时决定是否要继续通知;观察者模式的定义为: 定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新 从定义就可以看出,观察者模式主要就是两部分:主题(Subject)和观察者(Observer) 为了更清楚的了解观察者模式,下面将会用案例说明观察者模式; 天气预报项目 今天一个新的项目交到了你的手上,这个项目是一个天气预报公司的,他们想

YXXXYX的博客 5139

华为OD机试新系统真题-魔法咒语组合(Java/Py/C++/Go/C/Js)

华为OD机试 新系统真题【魔法咒语组合】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【魔法咒语组合】多语言题解

qq_45776114的博客 669

DDR5 JEDEC标准简析:一次读懂DDR5的核心规范!

JEDEC,全称是,中文名称是「电子元件工程联合委员会」,它是全球权威的存储接口标准制定机构。我们常见的 DDR2、DDR3、DDR4、DDR5 都是它搞出来的。📌 JEDEC 就像存储接口界的“裁判+编剧”——规定谁该怎么跑,怎么演,怎么配合。

weixin_43199439的博客 2571

23种设计模式一观察者模式

观察者模式是一种行为型设计模式,定义了对象间的一对多依赖关系,当被观察者状态变化时自动通知所有观察者。该模式包含被观察者(Subject)和观察者(Observer)两个核心角色,实现松耦合、动态绑定和广播通信。文章介绍了两种实现方式:基于Java内置的Observable/Observer类(已弃用)和更推荐的自定义接口实现。观察者模式广泛应用于框架设计(如Spring事件机制、Vue响应式原理),能提升系统的可维护性、扩展性和可测试性。通过天气监测系统的代码示例,展示了该模式的具体应用场景和工作流程。

J_liaty的博客 1218

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

设计模式 Day 4:观察者模式(Observer Pattern)深度解析

中文释义在对象间建立一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。设计哲学松耦合原则:主题与观察者之间通过抽象接口交互开闭原则:新增观察者无需修改主题代码事件驱动架构:状态变化触发连锁反应核心价值:建立松耦合的对象间动态依赖关系实现要点定义清晰的Subject-Observer接口管理观察者注册机制合理选择推/拉模型适用场景事件驱动架构跨模块状态同步需要广播通知的场合。

Interview_TC的博客 1311

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

浅谈Observer观察者模式

一、前言 观察者模式其实最好的名称应该是“发布订阅”模式,和我们现在大数据之中的发布订阅方式比较类似,但是也有区别的地方,在上一个设计模式,我们学习了仲裁者模式,其中当控件的状态发生改变的时候就会向仲裁者发出信息,让仲裁者进行仲裁,这其实和发布订阅非常的类似,但是用处是不一样的,仲裁者模式是用来解除复杂对象之间的相互调用的关系,从而独立出来进行开发,而观察者模式是在被观察者状态改变的时候被动的...

学Java,找哪吒 6062

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

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

【23种设计模式】观察者模式(Observer Pattern)

*** 目标(Subject)接口*/// 注册// 删除// 通知ProductSubject 接口定义了目标(具体目标)的通用方法,包括注册观察者、移除观察者和通知观察者。目标接口提供了一种规范,使得具体目标和具体观察者能够通过接口进行交互,实现松耦合的关系。/*** 观察者(Observer)接口:*/// 更新ProductObserver 接口定义了观察者的通用方法,包括接收目标通知的更新。

金鳞踏雨 1140

设计模式-Observer模式

观察者模式定义了对象间一对多的依赖关系,当一个对象(本文称其为目标对象)的状态发生改变时,所有依赖它的对象(本文称其为观察者对象)都会得到通知并被自动更新。可能描述有些抽象,请看下图:Observer模式描述了如何建立这种关系。这一模式中的关键对象就是目标(subject)和观察者(observer)。一个目标可以有任意数目的观察者,一但该目标状态发生变化,所有的观察者都会得到通知。而作为对这个通知的相应,每个观察者都会查询目标以使其状态与目标状态同步。这种交互又称为。

weixin_44438755的博客 1571

设计模式——观察者模式(Observer)

要想正确理解设计模式,首先必须明确它是为了解决什么问题而提出来的。 设计模式学习笔记,欢迎交流。 ——Shulin 转载请注明出处:http://blog.youkuaiyun.com/zhshulin 1、概念                  观察者模式是对象的行为模式,外号非常多...!!又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/V

在路上 5382

unity里很重要的设计模式 - 观察者模式(Observer)

unity游戏开发里最常用的是 singleton 和 observer 设计模式,下面这个链接 中的讲解非常好,是关于观察者模式的,而且还能学到C#中委托,事件的用法,接口,抽象类的知识。 http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html //////////////////////// 以防万一,...

lynon的专栏 1万+

JAVA设计模式(19):行为型-观察者模式(Observer)

观察者模式是设计模式中的“超级模式”,其应用随处可见,在之后几篇文章里,我将向大家详细介绍观察者模式。         “红灯停,绿灯行”,在日常生活中,交通信号灯装点着我们的城市,指挥着日益拥挤的城市交通。当红灯亮起,来往的汽车将停止;而绿灯亮起,汽车可以继续前行。在这个过程中,交通信号灯是汽车(更准确地说应该是汽车驾驶员)的观察目标,而汽车是观察者。随着交通信号灯的变化,汽车的行为

The Best Or Nothing~ 6435

Aurora安装后必做5件事:安全启动密钥注册、自动更新配置与新手桌面设置清单

Aurora 是基于 Fedora 的免维护 KDE 桌面系统,主打"装完即用、长期稳定"。刚完成 **Aurora 安装**后,建议按本指南依次完成**安全启动密钥注册、自动更新配置与新手桌面设置**这 5 件事,让系统既安全又省心,日常几乎零维护。 ## 快速认识 Aurora 一句话概括:Aurora 是一套开箱即用的生产力工作站,底层采用 Fedora + bootc(不可变系统),桌

gitblog_01064的博客 900

行为型设计模式之观察者模式

观察者模式(observer pattern)的原始定义是:定义对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖项都会自动得到通知和更新。身边有不少例子都属于这个,有兴趣,欢迎来看文章啊。

yajunjiao的专栏 683

设计模式 - 观察者Observer模式

观察者模式又叫做观察者(Observer)监听者(Listener)模式,也叫发布(Publish)订阅(Subscribe)模式,常用于解耦事件的观察和事件最终的处理方式,举个例子说明:例子:基于同一组数据,生成了很多不同的界面来显示,有曲线图显示方式,有圆饼图显示方式,有柱状图显示方式等等…,当底层数据发生改变时,所有基于同一组数据的图像显示都需要修改图像,那么此时有两种实现方式:1、所有图形界面模块都去观察底层数据是否做了改变,如果变化,那么读取数据,修改图像显示。

ljy的博客 1474

设计模式之观察者模式(Observer Pattern)

六大原则:单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则。 二十三设计模式:单例模式、Builder 模式、原型模式、工厂方法模式、抽象工厂模式、策略模式、状态模式、责任链模式、解释器模式、命令模式、观察者模式

Mr_Four 310
上一篇: 设计模式深入学习--Template Method模板方法模式(行为型模式)
下一篇: 设计模式深入学习--State 状态模式(行为型模式)
LonelySu
博客等级 码龄12年 8粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值