设计模式-观察者模式

观察者模式,又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象,这个主体对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

结构图:

 

 

实现代码:

 1     /// <summary>
 2     /// 抽象通知者
 3     /// </summary>
 4   abstract class Subject
 5     {
 6         private IList<MyObserver> observers = new List<MyObserver>();
 7         //添加抽象观察者
 8         public void Attach(MyObserver myObserver)
 9         {
10             observers.Add(myObserver);
11         }
12         //移除抽象观察者
13         public void Detach(MyObserver myObserver)
14         {
15             observers.Remove(myObserver);
16         }
17         //通知事件
18         public void Notify()
19         {
20             foreach (MyObserver observer in observers)
21             {
22                 observer.Update();
23             }
24         }
25     }
26     /// <summary>
27     /// 具体通知者
28     /// </summary>
29      class ConcreteSubject : Subject
30     {
31         //通知者状态
32         private string subjectState;
33 
34         public string SubjectState
35         {
36             get { return subjectState; }
37             set { subjectState = value; }
38         }
39     }
40     #endregion
41 
42     //抽象观察者
43     abstract class MyObserver
44     {
45         //派生类会继承并实现该方法
46         public abstract void Update();
47     }
48     //具体观察者 需要订阅通知者
49     class ConcreteObserver : MyObserver
50     {
51         private string Name;
52         private string observerstate;
53         private ConcreteSubject subject;
54 
55         public ConcreteObserver(string name, ConcreteSubject concretesubject)
56         {
57             Name = name;
58             subject = concretesubject;
59         }
60 
61         public override void Update()
62         {
63             observerstate = subject.SubjectState;
64             Console.WriteLine($"观察者{Name}的新状态是{observerstate}");
65         }
66     }

观察者模式包括这4个部分抽象通知者,具体通知者,抽象观察者,具体观察者。提取抽象使其更加通用。

调用代码如下:

1 ConcreteSubject mysubject = new ConcreteSubject();
2 mysubject.Attach(new ConcreteObserver("张三", mysubject));
3 mysubject.Attach(new ConcreteObserver("李四", mysubject));
4 mysubject.SubjectState = "通知者开始发送!";
5 mysubject.Notify();

结果如下:

 

 

优化:

在上述实现中,具体通知者还是需要显式添加具体观察者。是为了在通知时,调用各观察者的Update方法。

但在实际情况中,各观察者需要实现的方法都不相同。我们引入委托,定义一个EventHandler(事件处理程序),动态地添加各观察者的执行方法。

实现代码:

 1     interface ISubject
 2     {
 3         void Notify();
 4         string SubjcetState { get; set; }
 5     }
 6     //事件处理程序的委托
 7     delegate void EventHandler();
8 class ConcreteSubjectTest : ISubject 9 { 10 private string action; 11 public event EventHandler Update; 12 public void Notify() 13 { 14 Update(); 15 } 16 public string SubjcetState 17 { 18 get { return action; } 19 set { action = value; } 20 } 21 } 22 23 class ConcreteObserverTest 24 { 25 private string name; 26 private ConcreteSubjectTest concreteSubjectTest; 27 public ConcreteObserverTest(string name, ConcreteSubjectTest concreteSubjectTest) 28 { 29 this.name = name; 30 this.concreteSubjectTest = concreteSubjectTest; 31 } 32 33 public void OffWork() 34 { 35 Console.WriteLine("下班啦"); 36 } 37 }

调用代码:

1  ConcreteSubjectTest concreteSubjectTest = new ConcreteSubjectTest(); 
2  ConcreteObserverTest AA = new ConcreteObserverTest("王五", concreteSubjectTest);
3  concreteSubjectTest.Update += new Observer.EventHandler(AA.OffWork); 
4  concreteSubjectTest.Notify();

 

使用场景:事件总线的实现,在后面博客会更新。主要还是围绕高内聚,低耦合,提高可维护性

以上,仅用于学习和总结!

 

posted @ 2021-08-23 11:17  y_w_k  阅读(30)  评论(0编辑  收藏  举报