C# 观察者模式实例介绍
更新时间:2020年6月25日 11:44 点击:2128
观察者模式
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。
观察者结构图:
使用场景:老板回来通知员工需要进入工作状态。
定义观察者的抽象类:
abstract class Observer
{
protected string name;
protected ISubject sub;
public Observer(string name, ISubject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
}
看NBA直播的同事:
//使用OO
class NBAObserver : Observer
{
public NBAObserver(string name, ISubject sub)
: base(name, sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}关闭NBA直播,继续工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class NBAObserver2
{
private string name;
private ISubject2 sub;
public NBAObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseStockMarket()
{
Console.WriteLine("{0} {1}关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
看股票的同事:
//使用OO
class StockObserver : Observer
{
public StockObserver(string name, ISubject sub) : base(name,sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}关闭股票行情,继续工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class StockObserver2
{
private string name;
private ISubject2 sub;
public StockObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseNBA()
{
Console.WriteLine("{0} {1}关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
上的身份是订阅者,下面定义发布者:
//使用OO
interface ISubject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
class Boss : ISubject
{
private IList<Observer> observers = new List<Observer>();
private string action;
public void Attach(Observer observer)
{
observers.Add(observer);
}
public void Detach(Observer observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//使用事件和委托
interface ISubject2
{
void Notify();
string SubjectState
{
get;
set;
}
}
delegate void EventHandler();
class Boss2 : ISubject2
{
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
主函数调用:
class Program
{
static void Main(string[] args)
{
//观察者模式OO实现
Boss huhansan = new Boss();
StockObserver tongshi1 = new StockObserver("name1",huhansan);
NBAObserver tonshi2 = new NBAObserver("name2", huhansan);
huhansan.Attach(tongshi1);
huhansan.Attach(tonshi2);
huhansan.SubjectState = "我1回来了";
huhansan.Notify();
//观察者模式c#事件实现
Boss2 huhansan2 = new Boss2();
StockObserver2 tongshi3 = new StockObserver2("name3", huhansan2);
NBAObserver2 tonshi4 = new NBAObserver2("name4", huhansan2);
huhansan2.Update += new EventHandler(tongshi3.CloseNBA);
huhansan2.Update += new EventHandler(tonshi4.CloseStockMarket);
huhansan2.SubjectState = "我2回来了";
huhansan2.Notify();
Console.ReadKey();
}
}
委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的一个类,委托实例代表一个具体的函数,而且一个委托可以搭载多个方法,所有方法被依次唤醒。
1 观察者模式
一个简单的例子,比如说猫叫,老鼠跑,主人被惊醒。
在不知道观察者模式之前,我们的代码可能是这样的。
//老鼠类
class Mouse
{
public void Run()
{
Console.WriteLine("老鼠跑了!");
}
}
//主人类
class Master
{
public void Wake()
{
Console.WriteLine("主人醒了!");
}
}
//猫类
class Cat
{
public void Cry ()
{
Console.WriteLine("猫叫了!");
new Mouse().Run();//猫叫的同时,调用老鼠跑的方法。
new Master().Wake();//猫叫的同时,调用主人醒的方法。
}
}
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
cat.Cry();
Console.ReadLine();
}
}
这个代码基本上能实现所有的功能。但是,这个方法特别不利用扩展,
试想,如果,猫叫后,狗也叫,那是不是也要在猫叫的方法里重新加入狗叫的方法?
或者说,猫叫后,主人他老婆也醒了,是不是也要在猫叫的方法里加入他老婆醒的方法呢?
显然,这样的代码不利用维护,也不是面向对象的代码。
观察者模式能够很好的解决这个问题。
观察者模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并自动更新。在我们的例子中,猫和老鼠,主人,狗,主人他老婆是一对多的依赖,当猫叫时,所有依赖于它的对象都会自动执行某个操作。
观察者模式的实现,一般有下面四部分组成。
1.ISubject接口(抽象目标),含方法Notify,Register,UnRegister(名字可以自己任意取名)
2.Subject类(实体目标),实现ISubject接口,一般只有一个
3.IObservable接口(抽象观察者)。
4 Observer类(实体观察者),实现IObservable接口,一般有多个。
观察者模式中的“注册--通知--注销”图示:
1. 观察者(Observer)将自己(Regiester)注册到被观察对象(Subject)中,被观察对象将观察者放在一个容器(Container)。Container一般为Ilist,Arraylist等数据结构,存放多个IObservable接口变量。
2.当被观察对象(Subject)发生变化(如图中的AskPriceChanged)时,容器(Container)中的所有观察者(Observer)都得到通知(Notify 方法),此时观察者会自动执行某些方法。
3.当观察者不想继续观察被观察者时,可以注销(UnRegiester方法)
上面的例子中改造后变成:
1.ISubject接口:
interface ISubject
{
void Notify();//主题变动时,通知虽有观察者
void Regiester(IObservable o);//观察者注册
void UnRegiester(IObservable o);//观察者取消注册,此时主题发生任何变动,观察者都不会得到通知。
}
2.Subject 类:
class Cat : ISubject
{
private IList<IObservable> observers = new List<IObservable>();
public void Notify()
{
foreach (IObservable o in observers) //逐个通知观察者
{
o.Action();
}
}
public void Regiester(IObservable o)
{
if (o != null || !observers.Contains(o))
{
observers.Add(o);
}
}
public void UnRegiester(IObservable o)
{
if (observers != null && observers.Contains(o))
{
observers.Remove(o);
}
}
public void Cry()
{
Console.WriteLine("猫叫了!");
Notify();
}
}
3. IObservable 接口:
interface IObservable
{
void Action();//观察者对主题变动所对应的操作
}
4.Observer类(2个,Mouse和Master)
class Mouse : IObservable
{
public void Action()
{
Console.WriteLine("鼠跑了!");
}
}
class Master : IObservable
{
public void Action()
{
Console.WriteLine("主人醒了!");
}
}
5.主程序
Mouse mouse = new Mouse();
Master master = new Master();
Cat cat = new Cat();
cat.Regiester(mouse);
cat.Regiester(master);
cat.Cry();
Console.ReadLine();
这样就实现了观察者模式,通过把依赖类注册到主体类中,当主体类发生变化时,所有依赖类都得到了通知。如果需要扩展,比如说象上面例子的狗也叫了,我们可以定义一个狗类,然后在主程序中把狗对象注册到猫类中就可以了。如果不想依赖于猫类,也可以通过UnRegiester方法取消绑定。
同时,这也符合设计中的高内聚,低耦合的原则。
。
using System;
using System.Collections.Generic;
using System.Text;
namespace Sample
{
public delegate void CatCallEventHandler();
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Mouse mouse = new Mouse(cat);
Master master = new Master(mouse);
cat.Call();
}
}
class Cat
{
public event CatCallEventHandler catevent;
public void Call()
{
Console.WriteLine("喵喵.....");
catevent();
}
}
class Mouse
{
public event CatCallEventHandler mouseevent;
public Mouse(Cat cat)
{
cat.catevent += new CatCallEventHandler(this.MouseRun);
}
public void MouseRun()
{
Console.WriteLine("老鼠跑");
mouseevent();
}
}
class Master
{
public Master(Mouse mouse)
{
mouse.mouseevent+=new CatCallEventHandler(this.JingXing);
}
public void JingXing()
{
Console.WriteLine("主人被惊醒");
}
}
}
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。
观察者结构图:
使用场景:老板回来通知员工需要进入工作状态。
定义观察者的抽象类:
复制代码 代码如下:
abstract class Observer
{
protected string name;
protected ISubject sub;
public Observer(string name, ISubject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
}
看NBA直播的同事:
复制代码 代码如下:
//使用OO
class NBAObserver : Observer
{
public NBAObserver(string name, ISubject sub)
: base(name, sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}关闭NBA直播,继续工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class NBAObserver2
{
private string name;
private ISubject2 sub;
public NBAObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseStockMarket()
{
Console.WriteLine("{0} {1}关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
看股票的同事:
复制代码 代码如下:
//使用OO
class StockObserver : Observer
{
public StockObserver(string name, ISubject sub) : base(name,sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}关闭股票行情,继续工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class StockObserver2
{
private string name;
private ISubject2 sub;
public StockObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseNBA()
{
Console.WriteLine("{0} {1}关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
上的身份是订阅者,下面定义发布者:
复制代码 代码如下:
//使用OO
interface ISubject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
class Boss : ISubject
{
private IList<Observer> observers = new List<Observer>();
private string action;
public void Attach(Observer observer)
{
observers.Add(observer);
}
public void Detach(Observer observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//使用事件和委托
interface ISubject2
{
void Notify();
string SubjectState
{
get;
set;
}
}
delegate void EventHandler();
class Boss2 : ISubject2
{
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
主函数调用:
复制代码 代码如下:
class Program
{
static void Main(string[] args)
{
//观察者模式OO实现
Boss huhansan = new Boss();
StockObserver tongshi1 = new StockObserver("name1",huhansan);
NBAObserver tonshi2 = new NBAObserver("name2", huhansan);
huhansan.Attach(tongshi1);
huhansan.Attach(tonshi2);
huhansan.SubjectState = "我1回来了";
huhansan.Notify();
//观察者模式c#事件实现
Boss2 huhansan2 = new Boss2();
StockObserver2 tongshi3 = new StockObserver2("name3", huhansan2);
NBAObserver2 tonshi4 = new NBAObserver2("name4", huhansan2);
huhansan2.Update += new EventHandler(tongshi3.CloseNBA);
huhansan2.Update += new EventHandler(tonshi4.CloseStockMarket);
huhansan2.SubjectState = "我2回来了";
huhansan2.Notify();
Console.ReadKey();
}
}
委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的一个类,委托实例代表一个具体的函数,而且一个委托可以搭载多个方法,所有方法被依次唤醒。
1 观察者模式
一个简单的例子,比如说猫叫,老鼠跑,主人被惊醒。
在不知道观察者模式之前,我们的代码可能是这样的。
复制代码 代码如下:
//老鼠类
class Mouse
{
public void Run()
{
Console.WriteLine("老鼠跑了!");
}
}
//主人类
class Master
{
public void Wake()
{
Console.WriteLine("主人醒了!");
}
}
//猫类
class Cat
{
public void Cry ()
{
Console.WriteLine("猫叫了!");
new Mouse().Run();//猫叫的同时,调用老鼠跑的方法。
new Master().Wake();//猫叫的同时,调用主人醒的方法。
}
}
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
cat.Cry();
Console.ReadLine();
}
}
这个代码基本上能实现所有的功能。但是,这个方法特别不利用扩展,
试想,如果,猫叫后,狗也叫,那是不是也要在猫叫的方法里重新加入狗叫的方法?
或者说,猫叫后,主人他老婆也醒了,是不是也要在猫叫的方法里加入他老婆醒的方法呢?
显然,这样的代码不利用维护,也不是面向对象的代码。
观察者模式能够很好的解决这个问题。
观察者模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并自动更新。在我们的例子中,猫和老鼠,主人,狗,主人他老婆是一对多的依赖,当猫叫时,所有依赖于它的对象都会自动执行某个操作。
观察者模式的实现,一般有下面四部分组成。
1.ISubject接口(抽象目标),含方法Notify,Register,UnRegister(名字可以自己任意取名)
2.Subject类(实体目标),实现ISubject接口,一般只有一个
3.IObservable接口(抽象观察者)。
4 Observer类(实体观察者),实现IObservable接口,一般有多个。
观察者模式中的“注册--通知--注销”图示:
1. 观察者(Observer)将自己(Regiester)注册到被观察对象(Subject)中,被观察对象将观察者放在一个容器(Container)。Container一般为Ilist,Arraylist等数据结构,存放多个IObservable接口变量。
2.当被观察对象(Subject)发生变化(如图中的AskPriceChanged)时,容器(Container)中的所有观察者(Observer)都得到通知(Notify 方法),此时观察者会自动执行某些方法。
3.当观察者不想继续观察被观察者时,可以注销(UnRegiester方法)
上面的例子中改造后变成:
1.ISubject接口:
复制代码 代码如下:
interface ISubject
{
void Notify();//主题变动时,通知虽有观察者
void Regiester(IObservable o);//观察者注册
void UnRegiester(IObservable o);//观察者取消注册,此时主题发生任何变动,观察者都不会得到通知。
}
2.Subject 类:
复制代码 代码如下:
class Cat : ISubject
{
private IList<IObservable> observers = new List<IObservable>();
public void Notify()
{
foreach (IObservable o in observers) //逐个通知观察者
{
o.Action();
}
}
public void Regiester(IObservable o)
{
if (o != null || !observers.Contains(o))
{
observers.Add(o);
}
}
public void UnRegiester(IObservable o)
{
if (observers != null && observers.Contains(o))
{
observers.Remove(o);
}
}
public void Cry()
{
Console.WriteLine("猫叫了!");
Notify();
}
}
3. IObservable 接口:
复制代码 代码如下:
interface IObservable
{
void Action();//观察者对主题变动所对应的操作
}
4.Observer类(2个,Mouse和Master)
复制代码 代码如下:
class Mouse : IObservable
{
public void Action()
{
Console.WriteLine("鼠跑了!");
}
}
class Master : IObservable
{
public void Action()
{
Console.WriteLine("主人醒了!");
}
}
5.主程序
复制代码 代码如下:
Mouse mouse = new Mouse();
Master master = new Master();
Cat cat = new Cat();
cat.Regiester(mouse);
cat.Regiester(master);
cat.Cry();
Console.ReadLine();
这样就实现了观察者模式,通过把依赖类注册到主体类中,当主体类发生变化时,所有依赖类都得到了通知。如果需要扩展,比如说象上面例子的狗也叫了,我们可以定义一个狗类,然后在主程序中把狗对象注册到猫类中就可以了。如果不想依赖于猫类,也可以通过UnRegiester方法取消绑定。
同时,这也符合设计中的高内聚,低耦合的原则。
。
复制代码 代码如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace Sample
{
public delegate void CatCallEventHandler();
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Mouse mouse = new Mouse(cat);
Master master = new Master(mouse);
cat.Call();
}
}
class Cat
{
public event CatCallEventHandler catevent;
public void Call()
{
Console.WriteLine("喵喵.....");
catevent();
}
}
class Mouse
{
public event CatCallEventHandler mouseevent;
public Mouse(Cat cat)
{
cat.catevent += new CatCallEventHandler(this.MouseRun);
}
public void MouseRun()
{
Console.WriteLine("老鼠跑");
mouseevent();
}
}
class Master
{
public Master(Mouse mouse)
{
mouse.mouseevent+=new CatCallEventHandler(this.JingXing);
}
public void JingXing()
{
Console.WriteLine("主人被惊醒");
}
}
}
相关文章
- 当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
- 这篇文章主要为大家介绍了JavaScript设计模式中的观察者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 这篇文章主要介绍了Java经典设计模式之观察者模式,简单分析了观察者模式的概念、原理并结合实例形式给出了java观察者模式的具体用法与相关注意事项,需要的朋友可以参考下...2021-09-15
- 这篇文章主要介绍了C#中委托和事件在观察者模式中的应用,需要的朋友可以参考下...2020-06-25
- 一个简单的例子,比如说猫叫,老鼠跑,主人被惊醒,在不知道观察者模式之前,我们的代码可能是这样的...2020-06-25
- 这篇文章主要介绍了php观察者模式应用场景,结合完整实例形式详细分析了php观察者模式的具体定义与使用技巧,需要的朋友可以参考下...2017-02-09
- 这篇文章主要介绍了java设计模式中观察者模式,全文通过举例子及代码的形式进行了一个简单的介绍,希望大家能够理解并且学习到其中知识...2021-08-17
- 这篇文章主要介绍了C++设计模式之观察者模式,本文讲解了什么是观察者模式、观察者模式的UML类图、观察者模式的使用场合等内容,需要的朋友可以参考下...2020-04-25
- 设计模式中的观察者模式我相信很多php开发者都不是很了解了,下面一聚教程小编来为各位整理了一篇相关的文章供各位参考。 一些面向对象的编程方式,提供了一种构建对...2016-11-25
- 观察者模式也是php面向对象中的一个不常用的模式了,下面我们一起来看看php面向对象:观察者模式示例,希望对给各位带来帮助。 意图: 定义对象间的一种一对多的依赖关系...2016-11-25
- 这篇文章主要介绍了c# 使用计时器和观察者模式实现报警推送需求,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要为大家详细介绍了C++设计模式之观察者模式Observer,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
- 这篇文章主要介绍了C#设计模式之观察者模式实例讲解,本文详细讲解了观察者模式的定义、优缺点、代码实例等,需要的朋友可以参考下...2020-06-25
- 学习模式注重精髓而非模板,本文为了便于说明假定了三方并对三方功能进行了划分,实际应用并不拘泥于此。如果情况合适将数据(文档)类设计为单件模式也是一种很不错的选择...2020-06-25
- 这篇文章主要介绍了简单的观察者模式示例,抽象层定义了观察者模式,实现层是对抽象层的具体实现,需要的朋友可以参考下...2020-06-25
学习php设计模式 php实现观察者模式(Observer)
这篇文章主要介绍了php设计模式中的观察者模式,使用php实现观察者模式,感兴趣的小伙伴们可以参考一下...2015-12-14- 这篇文章主要介绍了PHP设计模式(观察者模式),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-07-07
- 这篇文章主要介绍了JAVA 观察者模式的的相关资料,文中代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-06-23
- 这篇文章主要介绍了C#中观察者模式的3种实现方式,本文讲解了利用.net的Event模型来实现、利用.net中IObservable<out T>和IObserver<in T>实现观察者模式、Action函数式方案等3种方法,需要的朋友可以参考下...2020-06-25
C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题示例
这篇文章主要介绍了C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题,简单讲述了观察者模式的原理并结合具体实例形式分析了使用观察者模式解决牛顿童鞋成绩问题的具体步骤相关操作技巧,并附带demo源码供读者下载参考,需要的朋友可以参考下...2020-06-25