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. JAVA 容易忽略的东西

    Java中的取余会出现负数.用Math.floorMod()方法可以掰正,但是也仅限被除数是负数的情况,如果除数是负数,这个没用. 和C不一样,Java中的字符串是不可变字符串,不能修改Java字符串 ...

  2. Go搭建后台服务学习记录

    资料: 1. go基础 https://juejin.im/entry/58329f84da2f600063074382 https://www.w3cschool.cn/go/ 2.go的一个orm ...

  3. Contest Setting 2018 ICPC Pacific Northwest Regional Contest dp

    题目:https://vj.69fa.cn/12703be72f729288b4cced17e2501850?v=1552995458 dp这个题目网上说是dp+离散化这个题目要对这些数字先处理然后进 ...

  4. 转://Oracle中定义者权限和调用者权限案例分析

    定义者权限:定义者权限指使用它所有者的权限,而不是当前用户来执行过程.因此,你可以限制用户执行的数据库操作,允许他们仅通过运行定义者权限的过程和函数访问数据.创建过程.函数和程序包的默认权限是定义者权 ...

  5. redis单例模式写法

    <?php /**只看红色重点 * =========================================================== * ZW_Memory_Cache * ...

  6. Spring Security(四):2.1 Introduction What is Spring Security?

    Spring Security provides comprehensive security services for Java EE-based enterprise software appli ...

  7. Spring Security(三):1、Getting Started

    The later parts of this guide provide an in-depth discussion of the framework architecture and imple ...

  8. python中如何对待易过期的cookies

    有时候,我们进行爬虫操作是,会使用reques的的post函数携带cookies访问目标网站已达到登录或者其他 目的,笔者最近就遇到了这样的案例,周六写好的代码,周一过来就不行了,重新登录访问目标网页 ...

  9. TMS-规划图

    规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 规划图 ...

  10. 探究如何永久更改Maven的Dynamic Web Project版本及pom.xml默认配置

    一:问题 在用eclipse创建一个maven project (webApp)时,我们一般会要进行许多麻烦的配置,比如 1.更改Java jdk版本为1.7或1.8(默认1.5) 2.补全src/m ...