zoukankan      html  css  js  c++  java
  • C#学习笔记-观察者模式

    题目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     /// <summary>
    20     /// 小秘
    21     /// 1.记下需要联系的同事们List<StockObserver>
    22     /// 2.增加需要联系的人员
    23     /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
    24     /// 4.秘密通知同事,老板回来了
    25     /// </summary>
    26     class Secretary
    27     {
    28         IList<StockObserver> stockOb = new List<StockObserver>();
    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(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     /// <summary>
    65     /// 看股票的同事
    66     /// 1.联系小秘,和小秘保持良好关系
    67     /// 2.根据小秘的偷偷通知修改自己的工作状态
    68     /// </summary>
    69     class StockObserver
    70     {
    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     /// <summary>
     20     /// 小秘
     21     /// 1.记下需要联系的同事们List<StockObserver>
     22     /// 2.增加需要联系的人员
     23     /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
     24     /// 4.秘密通知同事,老板回来了
     25     /// </summary>
     26     class Secretary
     27     {
     28         IList<Observers> observers = new List<Observers>();
     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     /// <summary>
     65     /// 观察者类
     66     /// 抽象类
     67     /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态
     68     /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可
     69     /// </summary>
     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     /// <summary>
     86     /// 看股票的同事
     87     /// 继承于观察者类
     88     /// 根据小秘的偷偷通知修改自己的工作状态
     89     /// </summary>
     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     /// <summary>
    104     /// 看NBA节目的同事
    105     /// 继承于观察者类
    106     /// 根据小秘的偷偷通知修改自己的工作状态
    107     /// </summary>
    108     class NBAObserver : Observers
    109     {
    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     /// <summary>
     31     /// 通知者的接口
     32     /// 不能用抽象类
     33     /// </summary>
     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> observers = new List<Observers>();
     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     /// <summary>
     84     /// 小秘:继承于接口
     85     /// 1.记下需要联系的同事们List<StockObserver>
     86     /// 2.增加需要联系的人员
     87     /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
     88     /// 4.秘密通知同事,老板回来了
     89     /// </summary>
     90     class Secretary:Subject
     91     {
     92         IList<Observers> observers = new List<Observers>();
     93         private string action;
     94         
     95         public string SecretAction
     96         {
     97             get
     98             {
     99                 return action;
    100             }
    101 
    102             set
    103             {
    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     /// <summary>
    129     /// 观察者类
    130     /// 抽象类
    131     /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态
    132     /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可
    133     /// </summary>
    134     abstract class Observers
    135     {
    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     /// <summary>
    150     /// 看股票的同事
    151     /// 继承于观察者类
    152     /// 根据小秘的偷偷通知修改自己的工作状态
    153     /// </summary>
    154     class StockObserver : Observers
    155     {
    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     /// <summary>
    168     /// 看NBA节目的同事
    169     /// 继承于观察者类
    170     /// 根据小秘的偷偷通知修改自己的工作状态
    171     /// </summary>
    172     class NBAObserver : Observers
    173     {
    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     /// <summary>
     24     /// 通知者的接口
     25     /// 不能用抽象类
     26     /// 现在抽象通知者由于不下网依赖抽象观察者,所以“增加”和“减少”的方法就没有必要了
     27     /// </summary>
     28     interface Subject
     29     {
     30         void Notify();
     31         string SecretAction
     32         {
     33             get; set;
     34         }
     35     }
     36 
     37     /// <summary>
     38     /// 委托就是一种引用方法的类型。
     39     /// 一旦为委托分配了方法,委托将于该方法具有完全相同的行为
     40     /// 委托方法的使用可以像任何其他方法一样,具有参数和返回值。
     41     /// 委托可以看做是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数
     42     /// 
     43     /// 一个委托可以搭载多个方法,所有的方法被依次唤起
     44     /// 最重要的是,它可以使得委托对象所搭载的方法并不需要属于同一个类
     45     /// 
     46     /// 委托对象所搭载的所有方法必须具有相同的原型和形式,也就是有相同的参数列表和返回值类型
     47     /// </summary>
     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     /// <summary>
     77     /// 小秘:继承于接口
     78     /// 1.记下需要联系的同事们List<StockObserver>
     79     /// 2.增加需要联系的人员
     80     /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
     81     /// 4.秘密通知同事,老板回来了
     82     /// </summary>
     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     /// <summary>
    111     /// 看股票的同事
    112     /// 根据小秘的偷偷通知修改自己的工作状态
    113     /// </summary>
    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     /// <summary>
    132     /// 看NBA节目的同事
    133     /// 根据小秘的偷偷通知修改自己的工作状态
    134     /// </summary>
    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

     总结:

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

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

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

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

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

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

  • 相关阅读:
    AspNetPage分页的RecordCount赋值问题
    bundle实现Activity之间的数据传递
    Windows Communication Foundation入门(Part Two) (转)
    数据库绑定TreeView,使用递归
    利用Repeater控件显示主-从关系数据表 (转)
    将TreeView中导出为XML数据
    JS调用WebService 无刷新获得在线消息
    table中取得各个单元格中的数据 parentElement children
    Oracle PL/SQL语言入门
    JavaScript直接导出Excel,Word
  • 原文地址:https://www.cnblogs.com/Aries-rong/p/7728060.html
Copyright © 2011-2022 走看看