C#中已经实现了观察者模式,那就是事件,事件封装了委托,使得委托的封装性更好,在类的内部定义事件,然后在客户端对事件进行注册:

 public class Subject
{
public event Action<int> MyEvent;
public async Task ExecuteEvent()
{
for (int i = ; i < ; i++)
{
await Task.Delay(TimeSpan.FromSeconds(0.1));
Console.Write(".");
if (i>)
{
MyEvent(i);
return;
}
}
} }
 class Program
{
static void Main(string[] args)
{
Subject sub = new Subject();
sub.MyEvent += (a) =>
{
Console.WriteLine($"the temprature is {a} now ,please shutdown!");
};
Task task= sub.ExecuteEvent();
Console.ReadKey();
}
}

可以说在C#中实现观察者模式是非常方便的。

观察者模式的定义:观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,他的所有依赖着都会收到通知并自动更新。

上面的例子可能比较简单,Subject类充当的就是一个主题,或者叫发布者,使用+=注册的lambda充当的就是一个订阅者,也就是Observer,(lambda表达式会生成一个匿名的类,更准确的说实际上这个匿名的类就是一个Observer)将会有很多的类似于这样的订阅者来对Subject的MyEvent事件进行注册,所以Subject和Observer是一对多的。当我们执行Subject中的ExecuteEvent方法时,就是在满足一定条件后发出通知,而Observer就会去执行相应的动作,这就是观察者模式。因为这个模式涉及到了对象和对象之间的依赖,这么这里又涉及到一个概念,那就是耦合。

设计原则:为了交互对象之间的松耦合而努力。

手动实现的观察者模式(java)

还是以headfirst设计模式这本书上的例子为依据,这个例子讲的是一个气象站(ISubject)和很多布告板(Observer)的故事,先上类图:

观察者模式中有两个角色,一个是Subject,主题角色,这个角色用来发布消息,另一个是Observer,观察者,用来接收消息。Subject和Observer的关系是一对多。

 /// <summary>
/// 定义一个主题对象的接口,主题对象可以发出通知。
/// 被观察者(IObserver)接受并做出相应的动作。
/// 主题对象和观察者之间是一对多的关系。
/// </summary>
public interface ISubject
{
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void NotifyObservers();
} public interface IObserver
{
void Update(float temp, float humidity, float pressure);
} public interface IDisplay
{
void Display();
}
/// <summary>
/// ConcreteSubject角色
/// </summary>
public class WeatherData:ISubject
{
private readonly IList<IObserver> _observers=new List<IObserver>();
public float Temp { get; set; }
public float Humidity { get; set; }
public float Pressure { get; set; }
public void RegisterObserver(IObserver observer)
{
_observers.Add(observer);
} public void RemoveObserver(IObserver observer)
{
_observers.Remove(observer);
} public void NotifyObservers()
{
foreach (IObserver item in _observers)
{
item.Update(Temp,Humidity,Pressure);
}
} public void SetMeasurements(float temp, float humidity, float pressure)
{
Temp = temp;
Humidity = humidity;
Pressure = pressure;
NotifyObservers();
}
}
public class CurrentConditionDisplay:IObserver,IDisplay
{
private float _temperature;
private float _humidity;
private ISubject _weatherData;
public CurrentConditionDisplay(ISubject weatherData)
{
_weatherData = weatherData;
_weatherData.RegisterObserver(this);
}
public void Update(float temperature, float humidity, float pressure)
{
_temperature = temperature;
_humidity = humidity;
Display();
}
public void Display()
{
Console.WriteLine($"out temperature is {_temperature},out humidity is {_humidity}");
} }

C#设计模式之3:观察者模式的更多相关文章

  1. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  2. Java设计模式之《观察者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...

  3. Java设计模式百例 - 观察者模式

    观察者(Observer)模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主体对象的状态变化会通知所有观察者对象.观察者模式又叫做发布-订阅(Publish/Subscribe ...

  4. [head first 设计模式]第二章 观察者模式

    [head first 设计模式]第二章 观察者模式 假如我们有一个开发需求--建造一个气象观测站展示系统.需求方给我们提供了一个WeatherObject对象,能够自动获得最新的测量数据.而我们要建 ...

  5. Java设计模式10:观察者模式

    观察者模式 观察者模式也叫作发布-订阅模式,也就是事件监听机制.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使他 ...

  6. 大话设计模式C++版——观察者模式

    观察者模式是一种类似于消息分发的模式,用于一个任务需要被多个对象监听的场景,或者成员对象需要反向通知类对象的情况,是一种很有用的设计模式.    这里以大话设计模式中的例子为例,办公室员工A.B.C在 ...

  7. 【C++深入浅出】设计模式学习之观察者模式

    前言 前两天学习了weak_ptr以后还是不甚明了,一则需要实际应用去锤炼,二来就是不懂观察者模式. 正文 观察者模式又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对 ...

  8. php设计模式之:观察者模式

    转载自php面向对象设计模式 之 观察者模式 问题 假如一个小贩, 他把产品的价格提升了, 不同的消费者会对此产生不同的反应.一般的编程模式无非是获取提升的价格,然后获取所有的消费者,再循环每个消费者 ...

  9. 我理解设计模式C++实现观察者模式Observer Pattern

    概述: 近期中国股市起起伏伏,当然了起伏就用商机,小明发现商机后果断想入市,买入了中国证券,他想在电脑client上,网页上,手机上,iPad上都能够查看到该证券的实时行情,这样的情况下我们应该怎么设 ...

  10. 设计模式学习之“观察者模式” [C#]

    <深入浅出设计模式>学习笔记第二章 需求: 开发一套气象监测应用,如图: 气象站,目前有三种装置,温度.湿度和气压感应装置. WeatherData对象追踪气象站的数据,并更新到布告板,布 ...

随机推荐

  1. ubuntu中利用qtcreator引用opencv249及采起采集卡的共享库

    opencv Link:https://github.com/opencv/opencv CqUsbCam link:https://github.com/niuxiaobaoer/CqUsbCam_ ...

  2. 【Linux基础】Linux常用命令汇总

    3-1文件目录操作命令(cd pwd mkdir rmdir rm) 绝对路径:由根目录(/)开始写起的文件名或目录名称, 例如 /home/dmtsai/.bashrc: 相对路径:相对于目前路径的 ...

  3. Linux的基础命令

    -shutdown –h now(root用户才有效)     立即关机 -shutdown –r now(root用户才有效)     立即重新启动计算机 -reboot               ...

  4. MySQL高级知识(二)——Join查询

    前言:该篇主要对MySQL中join语句的七种情况进行总结. 0.准备 join主要根据两表或多表之间列的关系,从这些表中进行数据的查询. 首先创建两张表:tb_emp(员工表)和tb_dept(部门 ...

  5. centos7下kubernetes(3。部署kubernetes)

    环境:三个centos7 K8s2是Master;K8s1是node1:K8s3是node2 官方文档:https://kubernetes.io/docs/setup/independent/ins ...

  6. 兼容Android 和 ios JavaScript copy paste

    <!DOCTYPE html> <html> <head> <title>关于我们Frame</title> <meta charse ...

  7. 【window】Windows10下为PHP安装redis扩展

    操作: 步骤1:D:\wamp\bin\apache\apache2.4.9\bin/php.ini中添加 ; php_redis extension=php_igbinary.dll extensi ...

  8. 吴恩达课后作业学习2-week2-优化算法

    参考:https://blog.csdn.net/u013733326/article/details/79907419 希望大家直接到上面的网址去查看代码,下面是本人的笔记 我们需要做以下几件事:  ...

  9. tomcat (选号)公司tomcat无页面解决

    问:我现在的有的解决方法就是把上一次war包下下载下来,在重启tomcat 答:那不行,更新war包就没有意义了,你都没排查故障  就直接说war包少东西?主页都没有..还能少主页也不是404.war ...

  10. linux学习问题总结

    目录 一.环境变量和普通变量的区别 二.rsyslog和logrotate会不会丢记录的问题 三.为什么有些文件夹大小不是4096的整数倍 四.reboot和shutdown等软链接实现原理 五.sy ...