博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#学习笔记-观察者模式
阅读量:5324 次
发布时间:2019-06-14

本文共 13689 字,大约阅读时间需要 45 分钟。

题目1:几个同事为了在上班期间偷偷看休息,做点其他的事情,就和小秘偷偷联系了一下,如果老板回来了,就麻烦小秘偷偷通知一声,这样方便大家及时变更自己的工作状态。

分析:

  根据题目分析,首先明确,肯定会有两个类:小秘类和同事类,分别描述与记录两种类型的人和行为。

  需要注意的是:小秘与同事构建联系的时候,一个小秘可能对应多位同事,所以这时需要利用List<>。

实现:

1     class Program 2     { 3         static void Main(string[] args) 4         { 5             Secretary lady = new Secretary(); 6             StockObserver num1 = new StockObserver("A", lady); 7             StockObserver num2 = new StockObserver("B", lady); 8  9             lady.Attach(num1);10             lady.Attach(num2);11 12             lady.SecretAction="boss is back";13             lady.Notify();14 15             Console.Read();16         }17     }18 19     /// 20     /// 小秘21     /// 1.记下需要联系的同事们List
22 /// 2.增加需要联系的人员23 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)24 /// 4.秘密通知同事,老板回来了25 ///
26 class Secretary27 {28 IList
stockOb = new List
();29 private string action;30 31 public string SecretAction32 {33 get34 {35 return action;36 }37 38 set39 {40 action = value;41 }42 }43 44 //增加需要联系的人员45 public void Attach(StockObserver ob)46 {47 stockOb.Add(ob);48 }49 50 //减少需要联系的人员51 public void Detach(StockObserver ob)52 {53 stockOb.Remove(ob);54 }55 56 //小秘通知了同事后,同事赶紧自行更改工作状态57 public void Notify()58 {59 foreach (StockObserver o in stockOb)60 o.Update();61 }62 }63 64 ///
65 /// 看股票的同事66 /// 1.联系小秘,和小秘保持良好关系67 /// 2.根据小秘的偷偷通知修改自己的工作状态68 /// 69 class StockObserver70 {71 private string name;72 private Secretary sec;73 74 public StockObserver(string name,Secretary sec)75 {76 this.name = name;77 this.sec = sec;78 }79 public void Update()80 {81 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction, name);82 }83 }
View Code

 

 

 

题目2:由于同事们人数众多,所以大家休闲的方式并不一致。

分析:

  同事们的休闲方式不同,他们彼此之间存在共同点与不同点。

  他们的共同点在于都需要与小秘联系且更新工作状态,同时他们的不同点也在于更新工作状态。

  所以相同点就不需要在子类中赘述,所以通过抽象类来将不同的方法设为抽象即可。

实现:

1     class Program  2     {  3         static void Main(string[] args)  4         {  5             Secretary lady = new Secretary();  6             StockObserver num1 = new StockObserver("A", lady);  7             NBAObserver num2 = new NBAObserver("B", lady);  8   9             lady.Attach(num1); 10             lady.Attach(num2); 11  12             lady.SecretAction = "boss is back"; 13             lady.Notify(); 14  15             Console.Read(); 16         } 17     } 18  19     ///  20     /// 小秘 21     /// 1.记下需要联系的同事们List
22 /// 2.增加需要联系的人员 23 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等) 24 /// 4.秘密通知同事,老板回来了 25 ///
26 class Secretary 27 { 28 IList
observers = new List
(); 29 private string action; 30 31 public string SecretAction 32 { 33 get 34 { 35 return action; 36 } 37 38 set 39 { 40 action = value; 41 } 42 } 43 44 //增加需要联系的人员 45 public void Attach(Observers ob) 46 { 47 observers.Add(ob); 48 } 49 50 //减少需要联系的人员 51 public void Detach(Observers ob) 52 { 53 observers.Remove(ob); 54 } 55 56 //小秘通知了同事后,同事赶紧自行更改工作状态 57 public void Notify() 58 { 59 foreach (Observers o in observers) 60 o.Update(); 61 } 62 } 63 64 ///
65 /// 观察者类 66 /// 抽象类 67 /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态 68 /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可 69 /// 70 abstract class Observers 71 { 72 protected string name; 73 protected Secretary sec; 74 75 public Observers(string name,Secretary sec) 76 { 77 this.name = name; 78 this.sec = sec; 79 } 80 81 public abstract void Update(); 82 } 83 84 85 ///
86 /// 看股票的同事 87 /// 继承于观察者类 88 /// 根据小秘的偷偷通知修改自己的工作状态 89 /// 90 class StockObserver:Observers 91 { 92 public StockObserver(string name, Secretary sec) 93 : base(name, sec) 94 { 95 } 96 97 public override void Update() 98 { 99 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction,name);100 }101 }102 103 ///
104 /// 看NBA节目的同事105 /// 继承于观察者类106 /// 根据小秘的偷偷通知修改自己的工作状态107 /// 108 class NBAObserver : Observers109 {110 public NBAObserver(string name, Secretary sec) 111 : base(name, sec)112 {113 }114 115 public override void Update()116 {117 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sec.SecretAction, name);118 }119 }
View Code

 

 

 

题目3:如果小秘突然有事情变得特别忙的时候,就没有了通知者,而此刻老板突然回来了,所以老板本身就变成了临时的通知者。

分析:

  老板本身变成了临时的通知者,虽然这个故事很不幸,但是客观分析,此刻老板的作用于小秘是一样的,所以老板应该和小秘继承于同一种父类。

  由于老板需要与观察者联系,而此刻的观察者已是抽象类,所以老板的父类不能再为抽象类了。

  原因如下:

  

  故此,老板和小秘只能通过接口来实现了。

实现:

1     class Program  2     {  3         static void Main(string[] args)  4         {  5             Boss boss = new Boss();  6   7   8             Secretary lady = new Secretary();  9             StockObserver num1 = new StockObserver("A", lady); 10             NBAObserver num2 = new NBAObserver("B", lady); 11  12             //lady没来的及通知两位同事 13             lady.Detach(num1); 14             lady.Detach(num2); 15  16             //现在的通知者就变成了boss 17             boss.Attach(num1); 18             boss.Attach(num2); 19  20             //num2没有看见boss回来,所以boss没来的及通知他 21             boss.Detach(num2); 22  23             boss.SecretAction = "boss is back"; 24             boss.Notify(); 25  26             Console.Read(); 27         } 28     } 29  30     ///  31     /// 通知者的接口 32     /// 不能用抽象类 33     ///  34     interface Subject 35     { 36         void Attach(Observers ob); 37         void Detach(Observers ob); 38         void Notify(); 39         string SecretAction 40         { 41             get;set; 42         } 43     } 44  45     class Boss : Subject 46     { 47         IList
observers = new List
(); 48 private string action; 49 50 public string SecretAction 51 { 52 get 53 { 54 return action; 55 } 56 57 set 58 { 59 action = value; 60 } 61 } 62 63 //增加需要联系的人员 64 public void Attach(Observers ob) 65 { 66 observers.Add(ob); 67 } 68 69 //减少需要联系的人员 70 public void Detach(Observers ob) 71 { 72 observers.Remove(ob); 73 } 74 75 //大家看见boss回来后,同事赶紧自行更改工作状态 76 public void Notify() 77 { 78 foreach (Observers o in observers) 79 o.Update(); 80 } 81 } 82 83 ///
84 /// 小秘:继承于接口 85 /// 1.记下需要联系的同事们List
86 /// 2.增加需要联系的人员 87 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等) 88 /// 4.秘密通知同事,老板回来了 89 ///
90 class Secretary:Subject 91 { 92 IList
observers = new List
(); 93 private string action; 94 95 public string SecretAction 96 { 97 get 98 { 99 return action;100 }101 102 set103 {104 action = value;105 }106 }107 108 //增加需要联系的人员109 public void Attach(Observers ob)110 {111 observers.Add(ob);112 }113 114 //减少需要联系的人员115 public void Detach(Observers ob)116 {117 observers.Remove(ob);118 }119 120 //小秘通知了同事后,同事赶紧自行更改工作状态121 public void Notify()122 {123 foreach (Observers o in observers)124 o.Update();125 }126 }127 128 ///
129 /// 观察者类130 /// 抽象类131 /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态132 /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可133 /// 134 abstract class Observers135 {136 protected string name;137 protected Secretary sec;138 139 public Observers(string name, Secretary sec)140 {141 this.name = name;142 this.sec = sec;143 }144 145 public abstract void Update();146 }147 148 149 ///
150 /// 看股票的同事151 /// 继承于观察者类152 /// 根据小秘的偷偷通知修改自己的工作状态153 /// 154 class StockObserver : Observers155 {156 public StockObserver(string name, Secretary sec)157 : base(name, sec)158 {159 }160 161 public override void Update()162 {163 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction, name);164 }165 }166 167 ///
168 /// 看NBA节目的同事169 /// 继承于观察者类170 /// 根据小秘的偷偷通知修改自己的工作状态171 /// 172 class NBAObserver : Observers173 {174 public NBAObserver(string name, Secretary sec)175 : base(name, sec)176 {177 }178 179 public override void Update()180 {181 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sec.SecretAction, name);182 }183 }
View Code

 

 

 

附:

实现:

1     class Program  2     {  3         static void Main(string[] args)  4         {  5             Boss boss = new Boss();  6             Secretary lady = new Secretary();  7   8             StockObserver num1 = new StockObserver("A", boss);  9             NBAObserver num2 = new NBAObserver("B", boss); 10              11             //将“看股票”的“关闭股票程序”方法和“看NBA者”的“关闭NBA直播”的方法 12             //挂钩到老板的“更新”上,也就是将两种不同类的不同方法委托给老板类的更新了。 13             boss.Update += new EventHandler(num1.CloseStockMarket); 14             boss.Update += new EventHandler(num2.CloseNBADirectSeeding); 15  16             boss.SecretAction = "boss is back"; 17             boss.Notify(); 18  19             Console.Read(); 20         } 21     } 22  23     ///  24     /// 通知者的接口 25     /// 不能用抽象类 26     /// 现在抽象通知者由于不下网依赖抽象观察者,所以“增加”和“减少”的方法就没有必要了 27     ///  28     interface Subject 29     { 30         void Notify(); 31         string SecretAction 32         { 33             get; set; 34         } 35     } 36  37     ///  38     /// 委托就是一种引用方法的类型。 39     /// 一旦为委托分配了方法,委托将于该方法具有完全相同的行为 40     /// 委托方法的使用可以像任何其他方法一样,具有参数和返回值。 41     /// 委托可以看做是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数 42     ///  43     /// 一个委托可以搭载多个方法,所有的方法被依次唤起 44     /// 最重要的是,它可以使得委托对象所搭载的方法并不需要属于同一个类 45     ///  46     /// 委托对象所搭载的所有方法必须具有相同的原型和形式,也就是有相同的参数列表和返回值类型 47     ///  48     delegate void EventHandler();   //委托 49  50     class Boss : Subject 51     { 52         public event EventHandler Update; 53  54         private string action; 55  56         public string SecretAction 57         { 58             get 59             { 60                 return action; 61             } 62  63             set 64             { 65                 action = value; 66             } 67         } 68  69         //大家看见boss回来后,同事赶紧自行更改工作状态 70         public void Notify() 71         { 72             Update(); 73         } 74     } 75  76     ///  77     /// 小秘:继承于接口 78     /// 1.记下需要联系的同事们List
79 /// 2.增加需要联系的人员 80 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等) 81 /// 4.秘密通知同事,老板回来了 82 ///
83 class Secretary : Subject 84 { 85 public event EventHandler Update; 86 87 private string action; 88 89 public string SecretAction 90 { 91 get 92 { 93 return action; 94 } 95 96 set 97 { 98 action = value; 99 }100 }101 102 103 //小秘通知了同事后,同事赶紧自行更改工作状态104 public void Notify()105 {106 Update();107 }108 }109 110 /// 111 /// 看股票的同事112 /// 根据小秘的偷偷通知修改自己的工作状态113 /// 114 class StockObserver 115 {116 private string name;117 private Subject sub;118 119 public StockObserver(string name,Subject sub)120 {121 this.name = name;122 this.sub = sub;123 }124 125 public void CloseStockMarket()126 {127 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SecretAction, name);128 }129 }130 131 /// 132 /// 看NBA节目的同事133 /// 根据小秘的偷偷通知修改自己的工作状态134 /// 135 class NBAObserver 136 {137 private string name;138 private Subject sub;139 140 public NBAObserver(string name,Subject sub)141 {142 this.name = name;143 this.sub = sub;144 }145 146 public void CloseNBADirectSeeding()147 {148 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SecretAction, name);149 }150 }
View Code

 

 

 

 总结:

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

  观察者模式所做的工作其实就是在接触耦合。让耦合的双方依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

 

 委托:就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数。

  一个委托可以搭载多个方法,所有方法被依次唤起。

  委托对象所搭载的方法并不需要属于同一个类。

 

 

 

注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。

转载于:https://www.cnblogs.com/Aries-rong/p/7728060.html

你可能感兴趣的文章
Django之Models
查看>>
CSS 透明度级别 及 背景透明
查看>>
Linux 的 date 日期的使用
查看>>
PHP zip压缩文件及解压
查看>>
SOAP web service用AFNetWorking实现请求
查看>>
Java变量类型,实例变量 与局部变量 静态变量
查看>>
mysql操作命令梳理(4)-中文乱码问题
查看>>
Python环境搭建(安装、验证与卸载)
查看>>
一个.NET通用JSON解析/构建类的实现(c#)
查看>>
Windows Phone开发(5):室内装修 转:http://blog.csdn.net/tcjiaan/article/details/7269014
查看>>
详谈js面向对象 javascript oop,持续更新
查看>>
关于这次软件以及pda终端的培训
查看>>
jQuery上传插件Uploadify 3.2在.NET下的详细例子
查看>>
如何辨别一个程序员的水平高低?是靠发量吗?
查看>>
新手村之循环!循环!循环!
查看>>
ASP.NET中Request.ApplicationPath、Request.FilePath、Request.Path、.Request.MapPath
查看>>
正则表达式的用法
查看>>
线程安全问题
查看>>
集合的内置方法
查看>>
IOS Layer的使用
查看>>