1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace 委托與發布訂閱者模式
8 {
9
10 /**
11 * 機器Machine為被訂閱者,維修工Repairer為訂閱者
12 * 工人(訂閱者)注冊機器的不同事件,並注冊回調函數以當相應事件發生時進行處理
13 * 不同的工人可以只關注他們各自感興趣的事件
14 */
15 // 機器類
16 public class Machine
17 {
18 // 機器是否正常工作狀態
19 public bool IsWorkWell { get; set; }
20
21 // 機器故障事件委托
22 public delegate void MachineBroken(string brokenMsg);
23 public event MachineBroken MachineBrokenEvent;
24
25 // 機器正常工作事件委托
26 public delegate void MachineWorkWell(string msg);
27 public event MachineWorkWell MachineWorkWellEvent;
28
29 // 機器運作
30 public void Run()
31 {
32 IsWorkWell = false; // 設置機器出故障
33
34 if (MachineBrokenEvent != null) // 有訂閱者注冊機器故障事件
35 {
36 if (!IsWorkWell)
37 MachineBrokenEvent("機器出故障了,速度過來看下啊,親~");
38 }
39
40 IsWorkWell = true; // 設置機器恢復正常
41
42 if (MachineWorkWellEvent != null) // 有訂閱者注冊機器運行正常事件
43 {
44 if (IsWorkWell)
45 MachineWorkWellEvent("機器正常運作,不用擔心,親~");
46 }
47 }
48
49 //public void OnMachineBrokenEvent(string brokenmsg)
50 //{
51 // MachineBroken handler = machineBrokenEvent;
52 // if (handler != null) handler(brokenmsg);
53 //}
54
55 //public void OnMachineWorkWellEvent(string msg)
56 //{
57 // MachineWorkWell handler = machineWorkWellEvent; 58 // if (handler != null) handler(msg);
59 //}
60 }
61
62 public interface IWorker
63 {
64 string Name { get; set; }
65 void DoJob(string msg);
66 }
67
68 // BusyWorker注冊機器故障事件
69 public class BusyWorker: IWorker
70 {
71 public string Name { get; set; }
72
73 public void DoJob(string msg)
74 {
75 Console.WriteLine(string.Format("{0}: 收到信息 < {1} > !馬上過來處理,稍等啊~", Name, msg));
76 }
77 }
78
79 // IdleWorker注冊機器正常工作事件
80 public class IdleWorker: IWorker
81 {
82 public string Name { get; set; }
83
84 public void DoJob(string msg)
85 {
86 Console.WriteLine(string.Format("{0}: 收到信息 < {1} > !非常好,這樣我就可以多睡會了~", Name, msg));
87 }
88 }
89
90 public class SubscriberPatternViaDelegate
91 {
92 static void Main(string[] args)
93 {
94 Machine machine = new Machine();
95
96 IWorker busyWorker = new BusyWorker();
97 busyWorker.Name = "Busy Worker";
98
99 IWorker idleWorker = new IdleWorker();
100 idleWorker.Name = "Idle Worker";
101
102 machine.MachineBrokenEvent += new Machine.MachineBroken(busyWorker.DoJob);
103 machine.MachineWorkWellEvent += new Machine.MachineWorkWell(idleWorker.DoJob);
104
105 ///////////////////////////////////////////////////////////////////////////////////////////
106 // 下面開始驗證是否可以為一個事件添加多個訂閱者
107 IWorker busyWorker2 = new BusyWorker();
108 busyWorker2.Name = "Busy Worker 2";
109 machine.MachineBrokenEvent += new Machine.MachineBroken(busyWorker2.DoJob);
110 // 試驗結果是可以的
111 // 同樣可以使用靜態委托,靜態委托的好處之一是節省了內存空間
112 ///////////////////////////////////////////////////////////////////////////////////////////
113
114 machine.Run(); // 機器開始運作
115
116 Console.ReadLine();
117 }
118 }
119 }