设计模式 试试 ( 事件代理 + 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 对象 都会对此 做出 反应;

 程序 运行结果 :

 

原文地址:https://www.cnblogs.com/ToDoToTry/p/1511114.html