首页 > 代码库 > 设计模式笔记8: 观察者模式

设计模式笔记8: 观察者模式

1.1  定义

  定义了一种一对多的依赖关系,让多个观察者同时监听一个对象,但这个对象发生变化时,会通知所有观察者对象,使他们能够更新自己。

 

1.2  类图

 

 

1.3  代码

 

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 namespace 观察者模式 8 { 9     // 委托  10     delegate void EventHandler();11 12     // 此时若需要增加一个看NBA的同事,就需要修改原有的类,违背开放封闭原则,而且此时他们都依赖于细节又违背了依赖倒转原则13     // 所以我们抽象一个父类解决这个问题14 15     // 观察者父类16     abstract class Observer17     {18         protected string name;19         protected Subject sub;20 21         public Observer(string name, Subject sub)22         {23             this.name = name;24             this.sub = sub;25         }26 27         // public abstract void Update();28     }29 30     // 看股票观察者31     class StockObserver : Observer32     {33 34         public StockObserver(string name, Subject sub)35             : base(name, sub)36         {37 38         }39         // 通知40         public void CloseStockMarket()41         {42             Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, this.name);43         }44     }45 46 47     // 看NBA观察者48     class NBAObserver : Observer49     {50         public NBAObserver(string name, Subject sub) : base(name, sub) { }51         public void CloseNBAPlay()52         {53             Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, this.name);54         }55     }56 57 58 59     // 通知者接口60     abstract class Subject61     {62         // 委托63         public EventHandler Update;64         public abstract void Notify();65         public string SubjectState { get; set; }66     }67 68     // 老板 实现通知者接口69     class Boss : Subject70     {71         public override void Notify()72         {73             Update();74         }75     }76 77     // 前台秘书78     // 前台秘书类也是一个具体的依赖,因为通知的对象可能是老板或其他对象。所以也需要抽象出来。79     class Secretary : Subject80     {81         // 通知82         public override void Notify()83         {84             Update();85         }86     }87 88 89 90 91 }
View Code

 

调用:

 

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6  7 namespace 观察者模式 8 { 9     class Program10     {11         static void Main(string[] args)12         {13             // 前台14             Subject s = new Boss();15             // 看股票的同事16             StockObserver t1 = new StockObserver("熊大", s);17             NBAObserver t2 = new NBAObserver("熊二", s);18 19             // 前台记录两个同事20             //s.Attach(t1);21             //s.Attach(t2);22             //s.Detach(t1); // 熊大没有被通知到23             // 老板回来通知同事24             s.Update += new EventHandler(t1.CloseStockMarket);25             s.Update += new EventHandler(t2.CloseNBAPlay);26             s.SubjectState  = "我胡汉三回来了!";27             s.Notify();28 29         }30     }31 }
View Code

 

 

1.4  总结

  我们定义观察者和通知者和通知者两个抽象父类都是为了面向抽象编程,以后再增加新的功能时增加新的类,而不修改原有的子类。 还有一个耦合:我们通知者对象通知观察者时执行的方法都是同一个方法。方法的执行体虽然已经被观察者重写,但是名字还是一致的。所以我们在通知者中增加了委托类型的成员,只需要将通知观察者的方法,注册给通知者的委托成员。这样就能完全自定义执行的方法了。

  

设计模式笔记8: 观察者模式