观察者模式

Posted 旅鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式相关的知识,希望对你有一定的参考价值。

模式:观察者模式又叫发布-订阅模式,即由单一发布源发出状态变化通知,订阅该变化的对象进行响应。

故事:最近工作中涉及到一个任务,界面上若干控件需要根据用户所处的状态来改变可用性,或进行相关的属性变化,对这个模型进行简化抽象就是一个观察者模式的经典适用场景。
类图如下:

时序图如下:

下面是对应的实现文件:

 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;
        }
    }
}

 

以上是关于观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

未调用 LiveData 观察者

Java设计模式补充:回调模式事件监听器模式观察者模式(转)

如何为片段设置观察者

永远观察实时数据的片段

设计模式观察者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

观察者模式