模式:观察者模式又叫发布-订阅模式,即由单一发布源发出状态变化通知,订阅该变化的对象进行响应。
故事:最近工作中涉及到一个任务,界面上若干控件需要根据用户所处的状态来改变可用性,或进行相关的属性变化,对这个模型进行简化抽象就是一个观察者模式的经典适用场景。
类图如下:
时序图如下:
下面是对应的实现文件:
UserStateEnum.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Observer { /// <summary> /// 用户状态枚举 /// </summary> public enum UserStateEnum { USER_STATE_1 = 0x001, USER_STATE_2 = 0x002, USER_STATE_3 = 0x004, USER_STATE_4 = 0x008, USER_STATE_5 = 0x010, USER_STATE_6 = 0x020, USER_STATE_7 = 0x040, USER_STATE_8 = 0x080 } }
UserState.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Observer { /// <summary> /// 用户状态改变事件参数 /// </summary> public class UserStateChangeEventArgs : EventArgs { public UserStateEnum State { get; set; } } /// <summary> /// 用户状态改变委托 /// </summary> /// <param name="sender">事件发起者</param> /// <param name="e">事件参数</param> public delegate void UserStateChangeHandle(object sender, UserStateChangeEventArgs e); /// <summary> /// 用户状态 /// </summary> public class UserState { private UserStateEnum _State; /// <summary> /// 用户当前状态 /// </summary> public UserStateEnum State { get { return _State; } set { if (_State != value) { _State = value; OnStateChange(); } else { _State = value; } } } /// <summary> /// 用户状态改变事件 /// </summary> public event UserStateChangeHandle StateChange; /// <summary> /// 触发用户状态改变事件 /// </summary> private void OnStateChange() { if (StateChange != null) { StateChange(this, new UserStateChangeEventArgs() { State = this.State }); } } } }
IUserStateControl.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Observer { /// <summary> /// 关联用户状态控件接口 /// </summary> interface IUserStateControl { /// <summary> /// 关联的用户状态 /// </summary> int AssociateState { get; set; } /// <summary> /// 响应用户状态变化的回调方法 /// </summary> /// <param name="sender">事件发起者</param> /// <param name="e">事件参数</param> void userStateChangeCallback(object sender, UserStateChangeEventArgs e); } }
Buttons.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Observer { public class Button : IUserStateControl { /// <summary> /// 按钮名称 /// </summary> public string Name { get; set; } /// <summary> /// 关联的用户状态 /// </summary> public int AssociateState { get; set; } /// <summary> /// 响应用户状态变化的回调方法 /// </summary> /// <param name="sender">事件发起者</param> /// <param name="e">事件参数</param> public void userStateChangeCallback(object sender, UserStateChangeEventArgs e) { if (((int)e.State & AssociateState) == 0) { Console.WriteLine(Name + " is disable"); } else { Console.WriteLine(Name + " is enable"); } } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Observer { class Program { static void Main(string[] args) { UserState state = new UserState(); Button btn1 = new Button(); btn1.Name = "btn1"; btn1.AssociateState = (int)(UserStateEnum.USER_STATE_2 | UserStateEnum.USER_STATE_3 | UserStateEnum.USER_STATE_4); state.StateChange += btn1.userStateChangeCallback; Button btn2 = new Button(); btn2.Name = "btn2"; btn2.AssociateState = (int)(UserStateEnum.USER_STATE_5 | UserStateEnum.USER_STATE_6 | UserStateEnum.USER_STATE_7); state.StateChange += btn2.userStateChangeCallback; Console.WriteLine("设置用户状态为:USER_STATE_1"); state.State = UserStateEnum.USER_STATE_1; Console.WriteLine("设置用户状态为:USER_STATE_2"); state.State = UserStateEnum.USER_STATE_2; Console.WriteLine("设置用户状态为:USER_STATE_5"); state.State = UserStateEnum.USER_STATE_5; Console.WriteLine("设置用户状态为:USER_STATE_8"); state.State = UserStateEnum.USER_STATE_8; Console.WriteLine("设置用户状态为:USER_STATE_3"); state.State = UserStateEnum.USER_STATE_3; Console.WriteLine("设置用户状态为:USER_STATE_6"); state.State = UserStateEnum.USER_STATE_6; } } }