1.软文推荐

2.软文推荐

3.软文推荐

观察者模式 是一种非常经典 非常常用的设计模式。

一个对象的行为 依赖于 另一个对象的状态。或者换一种说法,当被观察对象(目标对象)的状态发生改变时 ,会直接影响到观察对象的行为。

特点一 : 被观察者 和观察者 一般是 一对多的关系,一个被观察者 对应多个观察者,当一个被观察者的状态发生改变时,被观察者通知观察者, 然后可以在观察者内部 进行业务逻辑的处理。

使用场景

观察者模式所做的工作其实就是在解耦,让耦合的双方都依赖于抽象而不是具体,从而使得各自的变化都不会影响另一边的变化。

当一个对象的改变需要改变其他对象的时候,而且它不知道具体有多少对象有待改变的时候,应该考虑使用观察者模式。

一个抽象模型有两方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使得他们各自独立地改变和复用。

举例
public interface ISubject
{
   void Notify();

   string SubjectState { get; set; }
}
public class Boss : ISubject
{
   private readonly IList _observers = new List();

   public void Attach(Observer observer)
   {
       _observers.Add(observer);
   }

   public void Detach(Observer observer)
   {
       _observers.Remove(observer);
   }

   public void Notify()
   {
       foreach (var observer in _observers)
       {
           observer.Update();
       }
   }

   public string SubjectState { get; set; }
}

public abstract class Observer
{
   protected string Name;
   protected ISubject Subject;

   protected Observer(string name, ISubject subject)
   {
       Name = name;
       Subject = subject;
   }

   public abstract void Update();
}
public class StockObserver : Observer
{
   public StockObserver(string name, ISubject subject) : base(name, subject)
   {
   }

   public override void Update()
   {
       Console.WriteLine($"{Name} {Subject.SubjectState} 关闭股票行情,继续工作");
   }
}
public class NBAObserver : Observer
{
   public NBAObserver(string name, ISubject subject) : base(name, subject)
   {
   }

   public override void Update()
   {
       Console.WriteLine($"{Name} {Subject.SubjectState} 关闭 NBA 直播,继续工作");
   }
}


var boss = new Boss();
var stockObserver = new StockObserver("魏关姹", boss);
var nbaObserver = new NBAObserver("易管查", boss);

boss.Attach(stockObserver);
boss.Attach(nbaObserver);

boss.Detach(stockObserver);

boss.SubjectState = "老板我胡汉三回来了";
boss.Notify();

借助 event(委托) 我们可以实现可以灵活的观察者模式,我们定义了一个新老板来演示事件的方式,来看下面的示例:

public class NewBoss : ISubject
{
   public event Action Update;

   public void Notify()
   {
       Update?.Invoke();
   }

   public string SubjectState { get; set; }
}

public class GamePlayerObserver
{
   private readonly string _name;
   private readonly ISubject _subject;

   public GamePlayerObserver(string name, ISubject subject)
   {
       _name = name;
       _subject = subject;
   }

   public void CloseGame()
   {
       Console.WriteLine($"{_name} {_subject.SubjectState} 关闭 LOL 游戏,继续工作");
   }
}

var newBoss = new NewBoss();
var stockObserver = new StockObserver("魏关姹", boss);
var nbaObserver = new NBAObserver("易管查", boss);
var gameObserver = new GamePlayerObserver("西门", newBoss);

// 注册通知事件
newBoss.Update += stockObserver.Update;
newBoss.Update += nbaObserver.Update;
newBoss.Update += gameObserver.CloseGame;

newBoss.Update -= stockObserver.Update;

newBoss.SubjectState = "老板我胡汉三回来了";
newBoss.Notify();

从上面这个示例可以看到,通过事件的方式,我们可以不要求显示继承于 Observer 这个抽象类,可以更加灵活,扩展性更强,这也是很多类库中会使用事件来扩展的重要原因

More

设计模式要干的事情就是解耦。创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦,具体到观察者模式,它是将观察者和被观察者代码解耦。

根据应用场景的不同,观察者模式会对应不同的代码实现方式:有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。

在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项目开发中,这两种对象的称呼是比较灵活的,有各种不同的叫法,比如:Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener。不管怎么称呼,只要应用场景符合刚刚给出的定义,都可以看作观察者模式。

EventBus(事件总线) 就是一个观察者模式的实际应用。

本文来源:www.lxlinux.net/8824.html,若引用不当,请联系修改。

相关文章 8

1

DeinServerHost:德国服务器,I3-6100/16GB/1TB硬盘/30TB流量/1Gbps/DDOS/KVM,23/月 3分钟前

deinserverhost:德国服务器,I3-6100/16GB内存/1TB硬盘/30TB流量/1Gbps端口/DDOS/KVM,23/月。 deinserverhost怎么样,DeinServerHost是一家德国主机商,2013年成...

2

在FreeBSD上安装Bugzilla具体步骤 4分钟前

Bugzilla 是一个开源的缺陷跟踪系统(Bug-Tracking System),它可以管理软件开发中缺陷的提交(new),修复(resolve),关闭(close)等整个生命...

3

Linux下使用yum的方式安装mysql 7分钟前

本篇文章为大家分享一下Linux下使用yum的方式安装mysql具体方法, 有需要的小伙伴可以参考一下 \1. 先检查系统是否装有mysql [root@localhost~] ...

4

阿里云如何开启或关闭防火墙?如何开放安全组或开放端口(阿里云空调设备怎么开启?) 8分钟前

阿里云如何开启或关闭防火墙?阿里云服务器端口不通? 因为阿里云需要手动开放安全组(关闭防火墙),这个不是在vps层面操作的,而是需...

5

舍利云:日本vps云服务器;2核/2G/10GB SSD/100G流量/带宽5M起步/日本cn2,22.8元(舍利在中国) 8分钟前

舍利云是一家主要提供美国CERA GIA,美国精品vps,日本精品vps 香港精品vps 香港美国精品站群区vps云服务器,香港物理机(杜甫)和大陆拨号VPS。日...

6

路由器配置静态路由 11分钟前

学校有新旧两个校区,每个校区是一个独立的局域网,为了使新旧校区能够正常相互通讯,共享资源。每个校区出口利用一台路由器进行连...

7

网络建站教程哪里找?网络建站需要注意什么?(网站建站教程) 14分钟前

??现如今,人们对网络的依赖感越来越高,上网浏览网站已经成为一种常态,因此许多企业为了稳定自己的网络地位,会选择建设一个网站。...

8

Linux运维常用的40个命令 15分钟前

本篇文章重点为大家分享一下Linux运维常用的40个命令,有需要的小伙伴可以参考一下。 1、删除0字节文件 find- type f-size0- exec rm-rf{}\; 2、查看...