• 设计模式 试试 ( 事件代理 + factory Method+singleton+Observer)


          源码下载

          这个是 昨天 练习 事件代理 的时候想到 的.

    于是今天就 试一把

          由于昨天 写的 那个程序  

          基本功能: 在 Cat 类对象 Shout()  之后  订阅 事件 的 所有 Mouse 类对象都 会 执行 Run() 方法;. 

          

          但是 在每次 有 新的 事件订阅者的时候 必须 添加 一行 

    tomcat.CatShoutEvent +=new CatShoutEventHandler(jacky.run);      

    这一点我想  设计成 只要 声明了的mouse类对象 ,都会自动执行 响应函数;

    ok! 开始了    

           存在问题:      

    1. 如何在 对象 创建时 便让 其他类 知道 

    2. 如何 全局 获取 并通知 所有 对象执行相应的方法

     解决方法 : 用单例模式的思想 来获得 一个 对象 而且 该 使用 该对象 保存所有 Mouse 类的 对象的 引用 ,

                    同时应用 Observer 模式 , 通知所有 类对象 来执行 相应的方法..

    文件结构 

    │  AbstractCat.cs     ---------Cat   的   抽象类

    │  AbstractMouse.cs----------Mouse 的 抽象类 

    │  Cat.cs                 ----------Cat 类

    │  ITalk.cs               ----------Talk能力接口

    │  Mouse.cs            ----------Mouse

    │  Program.cs          ---------主函数 所在类

    │  ShoutEventArgs.cs---------时间参数类 继承自 EventArgs

    │  SuperCat.cs        ----------超级猫 类

    │  SuperMouse.cs   -----------超级 老鼠 类


    ├─MouseFactory      工厂方法所在包: 生产 老鼠

    │      IFactory.cs          -------工厂接口

    │      mouseFactory.cs  -------生产 Mouse 

    │      superMouseFactory.cs  --------生产超级老鼠

    ├─Observer                  ---------Observer模式 所在包: 

    │      IObserver.cs          ---------Observer接口

    │      Observable.cs      ----------- 事件通知者类: 其间 包含 所有 Mouse对象 的 引用 ,还有 通知 所有Mouse 对象 执行 对 猫的shout() 之后的 Action 方法

     将 Observer 声明为 接口 使得 所有的 实现了 该接口的 类 都可以 被通知 

           IObserver.cs:

    1  interface IObserver
    2     {
    3         void Action(object sender,ShoutEventArgs e);

    4     } 

     Observable.cs : 

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace delegateTry.Observer
     7 {
     8     class Observable
     9     {
    10         private IList<IObserver> mouses;
    11 
    12         private static Observable observable;
    13 
    14         private static readonly object syncForLock = new object();
    15 
    16         private Observable()
    17         {
    18             mouses = new List<IObserver>();
    19         }
    20 
    21         //单线程情况
    22         public static Observable GetInstance()
    23         {
    24             if (observable == null)
    25             {
    26                 observable = new Observable();
    27                 
    28                 return observable;
    29             }
    30 
    31             else
    32             {
    33                 return observable;
    34             }
    35         }
    36 
    37         //多线程
    38         /*
    39          * 在本程序中没用上
    40          */
    41 
    42         public static Observable GetInstanceForSecurity()
    43         {
    44             if (observable == null)
    45             {
    46                 lock (syncForLock)
    47                 {
    48                     if (observable == null)
    49                     {
    50                         observable = new Observable();                        
    51                     }
    52                 }
    53 
    54                 return observable;
    55             }
    56 
    57             else
    58             {
    59                 return observable;
    60             }
    61         }
    62 
    63         //添加 订阅者  或者说  观察者
    64         public void AddObserver(IObserver amouse)
    65         {
    66             this.mouses.Add(amouse);
    67         }
    68 
    69         //删除 订阅者  或者说 观察者 对象
    70         public void DelObserver(IObserver amouse)
    71         {
    72             this.mouses.Remove(amouse);
    73         }
    74 
    75 
    76         // 观察者 的反应
    77         public void Action(object  sender ,ShoutEventArgs e)
    78         {
    79             foreach (IObserver item in this.mouses)
    80             {
    81                 item.Action(sender,e);
    82             }
    83         }
    84 
    85     }
    86 }

    87  

    上面 使用单例 来 使得 所有 实现了 Iobserver 对象 的 引用 都可以  被 存放在 同一 个 对象中.; 并且 在 事件 被触发时 都被通知到

    如何 保证 Mouse 对象的 引用 都被 存放进 Observer 的同一个对象中 呢...?

          这里使用 factory Method 来 生产对象 同时 做一点 无耻的 工作.

    1     interface IFactory
    2     {
    3 
    4         AbstractMouse concreteMouse(string name);
    5 

    6     } 

     Mousefactory.cs  :

     1 class mouseFactory:IFactory
     2     {
     3 
     4         public AbstractMouse concreteMouse(string name)
     5         {
     6             AbstractMouse am =  new Mouse(name);
     7 
     8             //将其加入到   观察者对象列表中
     9             Observable.GetInstance().AddObserver(am);
    10 
    11             return am;
    12                  
    13         }
    14 
    15     }

    用这种方法 就在 生成对象 的时候 自动 的 将 引用 传递给了 Observer 对象 保存起来; 不用操心 了.

    大概就是这样 ,;

    贴一下  Mouse  和 Cat 类 的代码:

    因为 稍微做了一下 抽象 提取 所以 还蛮多的;

     1 public delegate void CatShoutEventHandler(object sender, ShoutEventArgs e);
     2 
     3    abstract  class AbstractCat
     4     {
     5         public event CatShoutEventHandler CatShoutEvent;
     6 
     7         protected string name;
     8 
     9 
    10         public AbstractCat(string name)
    11         {
    12             this.name = name;           
    13 
    14         }
    15 
    16 
    17         public string Name
    18         {
    19             get
    20             {
    21                 return name;
    22             }
    23         }
    24 
    25         public virtual void Shout()
    26         {
    27            
    28             if (this.CatShoutEvent != null)
    29             {
    30                 this.CatShoutEvent(thisnew ShoutEventArgs(this.name));
    31             }
    32 
    33         }

    34     } 

      1 class Cat:AbstractCat

     2     {
     3         public Cat(string name):base(name)
     4         {
     5             
     6         }
     7 
     8         public override void Shout()
     9         {
    10             Console.WriteLine(" 我只会 喵..喵..----普通猫 \n\n"this.name);
    11             base.Shout();
    12         }
    13     }

     1 class SuperCat:AbstractCat,ITalk
     2     {
     3         public SuperCat(string name)
     4             : base(name)
     5         { 
     6             
     7         }
     8 
     9         public string Talk()
    10         {
    11             return ("bull shit! cut your crap!\n");
    12         }
    13 
    14 
    15         public override void Shout()
    16         {
    17             Console.WriteLine("! this is {0}.! 哈哈.."this.name);
    18 
    19             Console.WriteLine(Talk());
    20 
    21             base.Shout();
    22 
    23         }
    24 
    25     }

    AbstractMouse 类

     1 abstract class AbstractMouse:IObserver
     2     {
     3         protected string name;
     4 
     5         public AbstractMouse(string name)
     6         {
     7             this.name = name;            
     8 
     9         }
    10 
    11         public virtual void run(object sender, ShoutEventArgs e)
    12         {
    13         
    14         }
    15 
    16         public virtual void Action(object sender, ShoutEventArgs e)
    17         {
    18             run(sender,e);
    19         }
    20 
    21     }
     1 class Mouse:AbstractMouse
     2     {
     3         public Mouse(string name)
     4             : base(name)
     5         { 
     6         
     7         }
     8         
     9 
    10         public override void run(object sender,ShoutEventArgs e)
    11         {
    12             Console.WriteLine(" {0}  来了, 我 {1} 开溜! ",e.ShoutSource,this.name);
    13         }
    14 

    15     }

     1 class SuperMouse:AbstractMouse,ITalk
     2     {
     3         public SuperMouse(string name):base(name)
     4         {
     5             
     6         }
     7 
     8         public string Talk()
     9         {
    10             return string.Format("  Stop !, this is {0}, Let's hava a negotiation! \n",this.name);
    11         }
    12 
    13         public override void run(object sender, ShoutEventArgs e)
    14         {
    15             if (sender is SuperCat)
    16             {
    17                 Console.WriteLine("{0} :: {1} \n", e.ShoutSource, Talk());
    18             }
    19 
    20             else
    21             {
    22 
    23                 Console.WriteLine(" 碰上个 傻瓜猫 今天快逃命吧 \n", e.ShoutSource, Talk());
    24 
    25             }
    26 
    27         }
    28 
    29 

    30     } 

     再看下主函数:

           1 class Program

     2     {
     3         static void Main(string[] args)
     4         {
     5             AbstractCat tomcat = new Cat("Tomcat");
     6             AbstractCat SuperTomcat = new SuperCat("超级猫");
     7 
     8             IFactory mouseFac = new mouseFactory();
     9             IFactory superFac = new superMouseFactory();
    10 
    11             AbstractMouse jacky = mouseFac.concreteMouse("Tacky");
    12             AbstractMouse mikky = mouseFac.concreteMouse("Mikky");
    13 
    14 
    15             AbstractMouse mickeyMouse = superFac.concreteMouse("米老鼠");
    16 
    17 
    18             tomcat.CatShoutEvent += new CatShoutEventHandler(Observable.GetInstance().Action);
    19 
    20             SuperTomcat.CatShoutEvent += new CatShoutEventHandler(Observable.GetInstance().Action);
    21 
    22 
    23             tomcat.Shout();
    24 
    25 
    26             Console.WriteLine("Tomcat shorting  ends here \n\n");
    27 
    28 
    29             Console.WriteLine("SuperTomcat shorting  begins here  \n\n");
    30 
    31 
    32             SuperTomcat.Shout();
    33 
    34 
    35             Console.Read();
    36 
    37         }
    38     }

    主程序中  在 Cat 对象 Shout() 之后 并未 声明 通知所有 的 Mouse 对象 ; 但是 所有的 Mouse 对象 都会对此 做出 反应;

     程序 运行结果 :

     

  • 相关阅读:
    Flink核心技术
    Flink学习问题和答案
    Spark知识点总结
    Scala知识点总结
    Spark测试题
    Hadoop概念试题
    IntelliJ IDEA 2019 快捷键终极大全
    Linux入门
    javaSe知识点总结
    Data
  • 原文地址:https://www.cnblogs.com/ToDoToTry/p/1511114.html
Copyright © 2020-2023  润新知