C#设计模式之十六观察者模式(Observer Pattern)【行为型】
一、引言 2.4、模式的组成 ?? ? ??? 可以看出,在观察者模式的结构图有以下角色: ??? (1)、抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。 ??? (2)、抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。 ??? (3)、具体主题角色(ConcreteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。 ??? (4)、具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的接口,以便使自身状态与主题的状态相协调。 2.5、观察者模式的代码实现 ??? 观察者模式在显示生活中也有类似的例子,比如:我们订阅银行短信业务,当我们账户发生改变,我们就会收到相应的短信。类似的还有微信订阅号,今天我们就以银行给我发送短信当我们账户余额发生变化的时候为例来讲讲观察者模式的实现,很简单,现实生活正例子也很多,理解起来也很容易。我们看代码吧,实现代码如下: 1 namespace 观察者模式的实现 2 { 3 //银行短信系统抽象接口,是被观察者--该类型相当于抽象主体角色Subject 4 public abstract class BankMessageSystem 5 { 6 protected IList<Depositor> observers; 7 8 构造函数初始化观察者列表实例 9 protected BankMessageSystem() 10 { 11 observers = new List<Depositor>(); 12 } 13 14 增加预约储户 15 void Add(Depositor depositor); 16 17 删除预约储户 18 Delete(Depositor depositor); 19 20 通知储户 21 Notify() 22 23 foreach (Depositor depositor in observers) 24 { 25 if (depositor.AccountIsChanged) 26 { 27 depositor.Update(depositor.Balance,depositor.OperationDateTime); 28 账户发生了变化,并且通知了,储户的账户就认为没有变化 29 depositor.AccountIsChanged = false; 30 } 31 } 32 33 } 34 35 北京银行短信系统,是被观察者--该类型相当于具体主体角色ConcreteSubject 36 sealed BeiJingBankMessageSystem : BankMessageSystem 37 38 39 override Add(Depositor depositor) 40 41 应该先判断该用户是否存在,存在不操作,不存在则增加到储户列表中,这里简化了 42 observers.Add(depositor); 43 44 45 46 Delete(Depositor depositor) 47 48 应该先判断该用户是否存在,存在则删除,不存在无操作,这里简化了 49 observers.Remove(depositor); 50 51 52 53 储户的抽象接口--相当于抽象观察者角色(Observer) 54 Depositor 55 56 状态数据 57 private string _name; 58 int _balance; 59 _total; 60 bool _isChanged; 61 62 初始化状态数据 63 protected Depositor(string name, total) 64 65 this._name = name; 66 this._balance = total;存款总额等于余额 67 this._isChanged = false;账户未发生变化 68 69 70 储户的名称,假设可以唯一区别的 71 Name 72 73 get { return _name; } 74 set { value; } 75 76 77 Balance 78 79 return this._balance; } 80 81 82 取钱 83 void GetMoney( num) 84 85 if (num <= this._balance && num > 0) 86 87 this._balance = this._balance - num; 88 true 89 OperationDateTime = DateTime.Now; 90 91 92 93 账户操作时间 94 public DateTime OperationDateTime { get; set; } 95 96 账户是否发生变化 97 AccountIsChanged 98 99 ._isChanged; } 100 this._isChanged =101 102 103 更新储户状态 104 void Update( currentBalance,DateTime dateTime); 105 106 107 北京的具体储户--相当于具体观察者角色ConcreteObserver 108 BeiJingDepositor : Depositor 109 110 public BeiJingDepositor(int total) : base(name,total) { } 111 112 113 114 Console.WriteLine(Name + ":账户发生了变化,变化时间是" + dateTime.ToString() + ,当前余额是" + currentBalance.ToString()); 115 116 117 118 119 客户端(Client) 120 Program 121 122 static void Main([] args) 123 124 我们有了三位储户,都是武林高手,也比较有钱 125 Depositor huangFeiHong = new BeiJingDepositor(黄飞鸿",3000); 126 Depositor fangShiYu = 方世玉1300127 Depositor hongXiGuan = 洪熙官2500128 129 BankMessageSystem beijingBank = new BeiJingBankMessageSystem(); 130 这三位开始订阅银行短信业务 131 beijingBank.Add(huangFeiHong); 132 beijingBank.Add(fangShiYu); 133 beijingBank.Add(hongXiGuan); 134 135 黄飞鸿取100块钱 136 huangFeiHong.GetMoney(100137 beijingBank.Notify(); 138 139 黄飞鸿和方世玉都取了钱 140 huangFeiHong.GetMoney(200141 fangShiYu.GetMoney(142 143 144 他们三个都取了钱 145 huangFeiHong.GetMoney(320146 fangShiYu.GetMoney(4330147 hongXiGuan.GetMoney(332148 149 150 Console.Read(); 151 152 153 }
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |