/// <summary> ///观察者模式 Observer Pattern 亦称: 事件订阅者、监听者、Event-Subscriber、Listener、Observe /// geovindu,Geovin Du eidt /// /// </summary> interface IObserver { /// <summary> /// /// </summary> /// <param name="celeb">对象</param> void Update(ICelebrity celeb); } /// <summary> /// / /// </summary> class ObserverType1 : IObserver { /// <summary> /// 名称 /// </summary> string nameOfObserver; /// <summary> /// / /// </summary> /// <param name="name">输入名称</param> public ObserverType1(String name) { this.nameOfObserver = name; } /// <summary> /// 更新 /// </summary> /// <param name="celeb"></param> public void Update(ICelebrity celeb) { Console.WriteLine($"{nameOfObserver} has received(接收) an alert from {celeb.Name}.Updated value is(更新标志值): {celeb.Flag}"); } } /// <summary> /// /// </summary> class ObserverType2 : IObserver { /// <summary> /// 名称 /// </summary> string nameOfObserver; /// <summary> /// /// </summary> /// <param name="name">输入名称</param> public ObserverType2(String name) { this.nameOfObserver = name; } /// <summary> /// 更新 /// </summary> /// <param name="celeb"></param> public void Update(ICelebrity celeb) { Console.WriteLine($"{nameOfObserver} notified(通知).Inside {celeb.Name}, the updated value is: {celeb.Flag}"); } } /// <summary> /// /// </summary> interface ICelebrity { /// <summary> /// Name of Subject /// 名称 /// </summary> string Name { get; } /// <summary> /// 标记 /// </summary> int Flag { get; set; } /// <summary> /// To register /// 注册 /// </summary> /// <param name="o"></param> void Register(IObserver o); /// <summary> /// To Unregister /// 取消注册 /// </summary> /// <param name="o"></param> void Unregister(IObserver o); ///<summary> ///To notify registered users ///注册用户 /// </summary> void NotifyRegisteredUsers(); } /// <summary> /// /// </summary> class Celebrity : ICelebrity { /// <summary> /// 对像数列 /// </summary> List<IObserver> observerList = new List<IObserver>(); /// <summary> /// 标记 /// </summary> private int flag; /// <summary> /// 标记 /// </summary> public int Flag { get { return flag; } set { flag = value; //Flag value changed. So notify observer(s). NotifyRegisteredUsers(); } } /// <summary> /// /// </summary> private string name; /// <summary> /// /// </summary> /// <param name="name">输入名称</param> public Celebrity(string name) { this.name = name; } //public string Name //{ // get // { // return name; // } //} //Or, simply use expression bodied //properties(C#6.0 onwards) /// <summary> /// /// </summary> public string Name => name; /// <summary> /// To register an observer. /// </summary> /// <param name="anObserver">对象</param> public void Register(IObserver anObserver) { observerList.Add(anObserver); } /// <summary> /// To unregister an observer. /// </summary> /// <param name="anObserver"></param> public void Unregister(IObserver anObserver) { observerList.Remove(anObserver); } /// <summary> /// Notify all registered observers. /// </summary> public void NotifyRegisteredUsers() { foreach (IObserver observer in observerList) { observer.Update(this); } } }
/// <summary> ///观察者模式 Observer Pattern 亦称: 事件订阅者、监听者、Event-Subscriber、Listener、Observe /// geovindu,Geovin Du eidt /// 产品 /// </summary> public class Product : INotifyPropertyChanged { /// <summary> /// 名特 /// </summary> private string name; /// <summary> /// 名称 /// </summary> public string Name { get => name; set { if (value == name) return; // critical name = value; OnPropertyChanged(); } } /// <summary> /// /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// /// </summary> /// <param name="propertyName"></param> [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return $"产品名称: {Name}"; } } /// <summary> /// 窗口 /// </summary> public class Window : INotifyPropertyChanged { /// <summary> /// /// </summary> private string productName; /// <summary> /// /// </summary> public string ProductName { get => productName; set { if (value == productName) return; // critical productName = value; OnPropertyChanged(); } } /// <summary> /// /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// /// </summary> /// <param name="propertyName"></param> [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return $"窗口: {ProductName}"; } } /// <summary> /// /// </summary> public sealed class BidirectionalBinding : IDisposable { /// <summary> /// /// </summary> private bool disposed; /// <summary> /// /// </summary> /// <param name="first"></param> /// <param name="firstProperty"></param> /// <param name="second"></param> /// <param name="secondProperty"></param> public BidirectionalBinding( INotifyPropertyChanged first, Expression<Func<object>> firstProperty, INotifyPropertyChanged second, Expression<Func<object>> secondProperty) { if (firstProperty.Body is MemberExpression firstExpr && secondProperty.Body is MemberExpression secondExpr) { if (firstExpr.Member is PropertyInfo firstProp && secondExpr.Member is PropertyInfo secondProp) { first.PropertyChanged += (sender, args) => { if (!disposed) { secondProp.SetValue(second, firstProp.GetValue(first)); } }; second.PropertyChanged += (sender, args) => { if (!disposed) { firstProp.SetValue(first, secondProp.GetValue(second)); } }; } } } /// <summary> /// /// </summary> public void Dispose() { disposed = true; } }
调用:
//观察者模式 Observer Pattern Console.WriteLine("***观察者模式 Observer Pattern Demonstration.***\n"); //We have 4 observers-2 of them are ObserverType1, 1 is of ObserverType2 IObserver myObserver1 = new ObserverType1("刘二"); IObserver myObserver2 = new ObserverType1("刘三"); IObserver myObserver3 = new ObserverType2("刘四"); IObserver myObserver4 = new ObserverType2("刘五"); Console.WriteLine("Working with first celebrity now."); ICelebrity celebrity = new Celebrity("Celebrity名人-1组"); //Registering the observers-Roy,Kevin,Bose celebrity.Register(myObserver1); celebrity.Register(myObserver2); celebrity.Register(myObserver3); Console.WriteLine(" Celebrity-1 is setting Flag 设置标志 = 5."); celebrity.Flag = 5; /* Kevin doesn't want to get further notification. So, unregistering the observer(Kevin)). */ Console.WriteLine("\nCelebrity-名人1组 is removing(移除) 刘三 from the observer list now."); celebrity.Unregister(myObserver2); //No notification is sent to Kevin this time. He has unregistered. Console.WriteLine("\n Celebrity-名人1组 is setting Flag 设置标志= 50."); celebrity.Flag = 50; //Kevin is registering himself again celebrity.Register(myObserver2); Console.WriteLine("\n Celebrity-名人1组 is setting Flag 设置标志= 100."); celebrity.Flag = 100; Console.WriteLine("\n Working with another celebrity now."); //Creating another celebrity ICelebrity celebrity2 = new Celebrity("Celebrity-名人2组"); //Registering the observers-Roy and Jacklin celebrity2.Register(myObserver1); celebrity2.Register(myObserver4); Console.WriteLine("\n --Celebrity-名人2组 is setting Flag value as设置标志 500.--"); celebrity2.Flag = 500; // var product = new Product { Name = "书" }; var window = new Window { ProductName = "书" }; // want to ensure that when product name changes // in one component, it also changes in another product.PropertyChanged += (sender, eventArgs) => { if (eventArgs.PropertyName == "Name") { Console.WriteLine("Name changed in Product"); window.ProductName = product.Name; Console.WriteLine("changed 1." + product); Console.WriteLine("changed 1." + window); } }; window.PropertyChanged += (sender, eventArgs) => { if (eventArgs.PropertyName == "ProductName") { Console.WriteLine("Name changed in Window"); product.Name = window.ProductName; Console.WriteLine("changed 2." + product); Console.WriteLine("changed 2." + window); } }; using var binding = new BidirectionalBinding( product, () => product.Name, window, () => window.ProductName); Console.WriteLine("1."+product); //书 Console.WriteLine("2."+window); // there is no infinite loop because of // self-assignment guard product.Name = "桌子"; window.ProductName = "椅子"; Console.WriteLine(product); Console.WriteLine(window); Console.ReadKey();
输出:
***观察者模式 Observer Pattern Demonstration.*** Working with first celebrity now. Celebrity-1 is setting Flag 设置标志 = 5. 刘二 has received(接收) an alert from Celebrity名人-1组.Updated value is(更新标志值): 5 刘三 has received(接收) an alert from Celebrity名人-1组.Updated value is(更新标志值): 5 刘四 notified(通知).Inside Celebrity名人-1组, the updated value is: 5 Celebrity-名人1组 is removing(移除) 刘三 from the observer list now. Celebrity-名人1组 is setting Flag 设置标志= 50. 刘二 has received(接收) an alert from Celebrity名人-1组.Updated value is(更新标志值): 50 刘四 notified(通知).Inside Celebrity名人-1组, the updated value is: 50 Celebrity-名人1组 is setting Flag 设置标志= 100. 刘二 has received(接收) an alert from Celebrity名人-1组.Updated value is(更新标志值): 100 刘四 notified(通知).Inside Celebrity名人-1组, the updated value is: 100 刘三 has received(接收) an alert from Celebrity名人-1组.Updated value is(更新标志值): 100 Working with another celebrity now. --Celebrity-名人2组 is setting Flag value as设置标志 500.-- 刘二 has received(接收) an alert from Celebrity-名人2组.Updated value is(更新标志值): 500 刘五 notified(通知).Inside Celebrity-名人2组, the updated value is: 500 1.产品名称: 书 2.窗口: 书 Name changed in Product Name changed in Window changed 2.产品名称: 桌子 changed 2.窗口: 桌子 changed 1.产品名称: 桌子 changed 1.窗口: 桌子 Name changed in Window Name changed in Product changed 1.产品名称: 椅子 changed 1.窗口: 椅子 changed 2.产品名称: 椅子 changed 2.窗口: 椅子 产品名称: 椅子 窗口: 椅子
标签:donet,Console,Name,core,Pattern,Celebrity,value,WriteLine,public From: https://www.cnblogs.com/geovindu/p/16770538.html