源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C# 观察者模式实例介绍

  • 时间:2020-12-06 17:46 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C# 观察者模式实例介绍
观察者模式 观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。 [b]观察者结构图:[/b] [img]http://files.jb51.net/file_images/article/201210/20121029214230315.gif[/img] 使用场景:老板回来通知员工需要进入工作状态。 定义观察者的抽象类:
[u]复制代码[/u] 代码如下:
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直播的同事:
[u]复制代码[/u] 代码如下:
//使用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); } }
看股票的同事:
[u]复制代码[/u] 代码如下:
//使用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); } }
上的身份是订阅者,下面定义发布者:
[u]复制代码[/u] 代码如下:
//使用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; } } }
主函数调用:
[u]复制代码[/u] 代码如下:
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(); } }
委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的一个类,委托实例代表一个具体的函数,而且一个委托可以搭载多个方法,所有方法被依次唤醒。 [b]1 观察者模式 [/b]一个简单的例子,比如说猫叫,老鼠跑,主人被惊醒。 在不知道观察者模式之前,我们的代码可能是这样的。
[u]复制代码[/u] 代码如下:
//老鼠类   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接口:
[u]复制代码[/u] 代码如下:
interface ISubject       {           void Notify();//主题变动时,通知虽有观察者           void Regiester(IObservable o);//观察者注册           void UnRegiester(IObservable o);//观察者取消注册,此时主题发生任何变动,观察者都不会得到通知。       }
2.Subject 类:
[u]复制代码[/u] 代码如下:
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 接口:
[u]复制代码[/u] 代码如下:
interface IObservable   {       void Action();//观察者对主题变动所对应的操作   }
4.Observer类(2个,Mouse和Master)
[u]复制代码[/u] 代码如下:
class Mouse : IObservable      {          public void Action()          {              Console.WriteLine("鼠跑了!");          }      }      class Master : IObservable      {          public void Action()          {              Console.WriteLine("主人醒了!");          }      }
5.主程序
[u]复制代码[/u] 代码如下:
Mouse mouse = new Mouse();              Master master = new Master();              Cat cat = new Cat();              cat.Regiester(mouse);              cat.Regiester(master);              cat.Cry();              Console.ReadLine();
这样就实现了观察者模式,通过把依赖类注册到主体类中,当主体类发生变化时,所有依赖类都得到了通知。如果需要扩展,比如说象上面例子的狗也叫了,我们可以定义一个狗类,然后在主程序中把狗对象注册到猫类中就可以了。如果不想依赖于猫类,也可以通过UnRegiester方法取消绑定。 同时,这也符合设计中的高内聚,低耦合的原则。 。
[u]复制代码[/u] 代码如下:
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("主人被惊醒");         }     } }
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部