C#实现观察者模式

概念的东西我就不讲了,网上一大堆,我们直接进入正题。假设有这样一个场景:用户输入账号、密码,登录成功后,需要给用户发送一条短信并增加5积分,代码如下:

相信很多人会这样写,包括我自己。这样写非常简单,一般情况下也没什么问题,但扩展性很差。比如我现在想加一个功能:登录成功后需要记录用户IP等到日志中。这时我们又要再加一个LogService来处理,代码如下:

这时我们发现不对劲了,这样代码耦合的太严重了,我们完全可以把登录成功后的一堆业务封装成单独的模块,用户在登录成功后,只要通知这个模块就行了。代码如下:

上面的代码我就不多解释了,实在太简单了。主要就是定义一个订阅接口:LoginSuccessObserver,外加三个实现类,每个实现类中取出封装好的message参数进行对应的业务处理。我们再看下登录的地方是怎么实现通知的(PS:期望不要太高,其实就一个for循环)。代码如下:

上面的代码相信大家都能看的懂,就是在UserController类中增加一个订阅者列表:LoginSuccessObservers,然后登录成功后,遍历这个列表进行业务处理就行。由于对登录业务没有影响,所以我们上面另开了一个线程进行发送通知。然后下面有两个方法:增加、删除订阅者。在调用的地方,只要按自己需要增加订阅者就行了。代码如下:

到此为止,观察者模式我们就讲完了,相信大家已经理解这个模式了。也许你会说你举的例子怎么和我之前看到的不太一样,委托呢?事件呢?你说的肯定是“水到100度就滴滴响”的例子。其实怎么说呢,用这种循环的方式,还是用事件委托的方式并不重要,重要的是你能辨别出场景。我们也可以给一个委托事件的版本,改造下,代码如下:

其实就是用事件换掉原来的订阅者列表,本质上是一样,无非就是向事件或列表中添加订阅者,我们再看下调用地方怎么改造。代码如下:

这段我就不解释了,相信大家都看的懂,最后我们来简单总结一下:

  • 观察者模式本质上就是订阅-发布模式,即一个对象内部发生了一件事,要通知给对这件事有兴趣的对象列表。最重要的是要识别出谁是发布者(Subject),谁是订阅者(Observer)。

  • 上面的例子是在单个进程内通知,也可以使用消息队列,比如RabbitMQ,进行多进程间的解耦。

今天讲的内容非常简单,如果能帮到你一点点,我就会很开心了,哈哈。

高冷地说声拜拜~~