c#之观察者模式
2021-05-04 09:27
标签:images namespace return 显示 接口 时间 委托和事件 程序员 png 观察者模式 前言:最近花心思学习了一下设计模式,总体感觉设计模式主要是给我们提供解决问题的一种思路,是自己的代码可重用性高,保证代码的可靠性,设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。 大家通过上面的故事:这个事情就是一个典型的观察者模式。 定义: 观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生改变的时候,会通知所有的观察者对象,使他们能够自动的进行更新。 我们先给出图形方便大家的理解,如下:
我们首先定义抽象通知类接口,通过我们的开放-封闭原则和依赖倒转原则,我们应该让程序都依赖于抽象,而不是相互依赖。我们选择了定义抽象通知类接口,代码如下: 好的我们的抽象的通知者已经定义好了,接下来我们定义抽象的观察者,我们各个的观察者都需要一个更新自身的状态的方法.代码如下: 接下来我们定义看股票观察者看NBA观察者并分别继承抽象观察者类,详细代码如下: 前台的调用的代码,详细代码如下: 截图显示:
观察者模式的特点 我们接下来需要思考一个问题:用观察者模式的动机的什么呢? 将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维护一致性而是各类紧密耦合,这样会给维护,扩展和重用带来不便。 我们什么使用使用观察者模式呢:当一个对象的改变需要同时的改变其他的对象的时候。 其实当我们的通知者发出消息的时候,并不知道谁是他的观察者,也就是说,具体观察者是谁,他根本不需要知道是谁。而任何一个观察者也不知道也不需要知道其他的观察者的存在。 总体来说:观察者所做的工作其实是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不影响到另一边的变化。 观察者模式的不足 尽管我们用了依赖倒转原则,但是抽象通知者还是依赖于抽象观察者,也就是说,万一没有了抽象观察者这样的接口的实现,这边的功能就实现不了了。 我们接下来的改造:我们只需要在通知者中广播一个方法,至于是谁关注他不管,如果观察者对这条信息感兴趣就关注,不感兴趣就不关注。 事件委托实现观察者模式(推荐使用) 定义抽象通知者接口,代码如下: 定义抽象观察者,代码如下: 观察者的实现类,代码如下: 客户端代码的调用,代码如下: 调试结果截图如下:
这样的话委托和事件的方式很好的实现了观察者模式!!好的我们的观察者模式就讲解完了,大家有什么问题和建议请大家积极的发言,明天就是10.24,程序员节快乐。 c#之观察者模式 标签:images namespace return 显示 接口 时间 委托和事件 程序员 png 原文地址:http://www.cnblogs.com/MoRanQianXiao/p/7719810.html
首先我们通过一个故事来进行探讨:在曾经的一段时间里,我们的股市是非常火爆的,几乎接近了全名炒股的程度,张三(化名)经常会在上班的时候关注股市的信息,但总是会担心老板出现在自己的身后,这样总归是不太好的。在这个时候,张三想到了一个办法,在它的公司有一个前台的秘书,平常没事的时候经常找她聊聊天,关系也是挺不错的。这时候他就请前台的秘书(小童)请她帮忙,如果老板的时候让她提前打个招呼。这样就不会怕发现了。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
///
那么接下来该定义抽象通知者的实现类了,我们继承的接口必须要实现里面全部的方法。全部代码的实现如下:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
class LookNBAObserver : Observer
{
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 观察者模式
{
class Program
{
static void Main(string[] args)
{
//前台花花
FrontDesk frontDesk = new FrontDesk();
//看屁股(哈哈哈)的同事
StockObserver stockObserver = new StockObserver("张雷", frontDesk);
//看NBA的同事
LookNBAObserver lookNbaObserver = new LookNBAObserver("骚鹏", frontDesk);
//增加观察者
frontDesk.Attach(stockObserver);
frontDesk.Attach(lookNbaObserver);
//花花发送消息,老板回来了
frontDesk.SubjectState = "老板回来了";
//减少观察者,这时候我不想通知张雷了,等着被老板抓吧,哈哈。
frontDesk.Detach(stockObserver);
//发出消息
frontDesk.Notify();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
interface Subject
{
//发送通知
void Notify();
//前台的状态
string SubjectState { get; set; }
}
}
定义前台类实现接口,代码如下:using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
//委托的声明
delegate void EventHandler();
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
abstract class Observer
{
//名字
protected string name;
//对通知者的引用
protected Subject sub;
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
class StockObserver : Observer
{
public StockObserver(string name, Subject sub) : base(name, sub)
{
//感兴趣进行关注,进行事件的注册
FrontDesk.Update += Update;
}
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
class NBAObserver : Observer
{
public NBAObserver(string name, Subject sub) : base(name, sub)
{
//事件的注册
FrontDesk.Update += Update;
}
public override void Update()
{
Console.WriteLine("{0} {1},关闭NBA直播,继续工作", sub.SubjectState, name);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托与事件的方式实现观察者模式
{
class Program
{
static void Main(string[] args)
{
//前台花花
FrontDesk huahua = new FrontDesk();
//看股票的同事
new StockObserver("张三", huahua);
//看NBA直播的同事
new NBAObserver("李四", huahua);
huahua.SubjectState = "老板来了";
//消息的发送
huahua.Notify();
Console.ReadKey();
}
}
}