设计模式--观察者模式(未完成)

概念

    我们都知道解决一个问题有N种解决方式,但在面向对象的设计中如何能做到“高内聚,低耦合”,设计可重用的对象才是我们追求的。
    观察者模式有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

理解

  • 我们可以把观察目标理解为主动方、发布方、主体等;
  • 把观察者理解为被动方、订阅方、观察器等。
  • 目标是整个行为链的源头,其它观察者都依赖于它的变化而作出响应。
  • 为了实现低耦合,我们不能使用“直接调用”的方式而需要利用“关注 – 通知”的机制去完成设计。
  • 通俗地说就是观察者“关注”目标它的改变,而目标发生改变后就“通知”所有已经“关注”了它的改变的观察者,从而执行“关注”的内容.
  • 这种机制的好处在于降低耦合度,分工明确,目标只负责在自身状态发生改变或做出某种行为时,向自身的”关注”清单发出“通知”,而不是直接调用观察者的行为(方法);
  • 观察者只负责“关注”目标它的变化,以及定义自身在收到目标“通知”后所需要做出的具体行为(也就是订阅的内容)。
  • 比如:就像博客一样,关注了我之后,我更新一篇文章,你就会收到通知,没关注我,我肯定也没办法塞给你,想要看到我的文章,关注走一波是不是就很方便了

- 主要作用

将一个系统分割成一些相互协作的类,有一个不好的副作用,那就是需要维护相关对象间的一致性。这样会给维护、扩展和重用都带来不便。观察者模式就是解决类与类之间的的耦合关系的。

观察者代码示例

观察者基类
(泛型在这里不做多的介绍,主题是观察者模式)

/// <summary>
/// 观察者派发基类
/// </summary>
/// <typeparam name="T">子类(实现单利)</typeparam>
/// <typeparam name="P">事件的参数</typeparam>
/// <typeparam name="X">字典键的类型</typeparam>
public class DispatcherBase<T, P, X> : IDisposable
    where T : new()//子类必须能new出实例
    where P : class//事件的参数必须是类
{

    #region 单例
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new T();
            }
            return instance;
        }
    }


    public virtual void Dispose()
    {

    }

    #endregion

    #region 属性
    /// <summary>
    /// 委托原型
    /// </summary>
    /// <param name="p">泛型P 子类可以根据需要改变参数类型</param>
    public delegate void OnActionHandler(P p);
    //存放观察者的字典
    //键X可以理解为 关注了我的博客
    //值List可以理解为关注我的人,
    //委托OnActionHandler可以理解为我改变了你们的动作(立马看/无视它/等有空了看...)
    public Dictionary<X, List<OnActionHandler>> dic = new Dictionary<X, List<OnActionHandler>>();
    #endregion

    #region 添加监听 AddEventListener
    /// <summary>
    /// 添加监听(通过这个函数可以关注我的博客)
    /// </summary>
    /// <param name="key">关注的类型(我的博客)</param>
    /// <param name="handler">具体动作(立马看/无视它/等有空了看...)</param>
    public void AddEventListener(X key, OnActionHandler handler)
    {
        //字典中有这个类型
        //有人关注过我,我有粉丝群
        if (dic.ContainsKey(key))
        {
            //获取对应类型的集合,把委托加进去
            //把新来的人加入到我的粉丝圈里
            dic[key].Add(handler);
        }
        //字典中没有这个类型
        //没人关注我,我还没有粉丝群
        else       
         {
             //新建一个粉丝群
            List<OnActionHandler> lstHandler = new List<OnActionHandler>();
            //新来的加到粉丝群里
            lstHandler.Add(handler);
            //我对应我的粉丝群(key是我,lstHandler是粉丝群)
            //key是关注的类型
            //lstHandler是观察者
            dic[key] = lstHandler;
        }
    }
    #endregion

    #region 移除监听 RemoveEventListener
    /// <summary>
    /// 移除监听(不关注我的博客了)
    /// </summary>
    /// <param name="protoCode"></param>
    /// <param name="handler"></param>
    public void RemoveEventListener(X key, OnActionHandler handler)
    {
        //想要解除关注首先得有被观察者
        //假如我不存在,你说不关注我了,可是我本来就不存在啊(想要不关注我,首先我得是存在的)
        if (dic.ContainsKey(key))
        {
            //观察者们(粉丝群)
            List<OnActionHandler> lstHandler = dic[key];
            //移除对应的观察者handler
            //把不关注我的人踢出粉丝群
            lstHandler.Remove(handler);
            //如果我的粉丝群没有一个人就解散粉丝群
            if (lstHandler.Count == 0)
            {
                dic.Remove(key);
            }
        }
    }
    #endregion

    #region 派发 Dispatch
    /// <summary>
    /// 派发事件通知观察者(通知关注我的人,我更新博客了)
    /// </summary>
    /// <param name="key"></param>
    /// <param name="param"></param>
    public void Dispatch(X key, P p = null)
    {
        //想要通知我的粉丝首先得有"我"
        if (dic.ContainsKey(key))
        {
            //粉丝群
            List<OnActionHandler> lstHandler = dic[key];
            //判断这个粉丝群是不是真的存在(里面有没有人)
            if (lstHandler != null && lstHandler.Count > 0)
            {
                //给每个观察者通知
                for (int i = 0; i < lstHandler.Count; i++)
                {
                    //判断观察者是不是存在
                    if (lstHandler[i] != null)
                    {
                        //通知了观察者
                        //p为参数,泛型自定义
                        //我可以通知粉丝我更新了什么文章
                        //也可以不说我更新了什么文章
                        lstHandler[i](p);
                    }
                }
            }
        }
    }

    #endregion

}

子类

/// <summary>
/// UI事件的观察者
/// </summary>
public class UIDispatcher : DispatcherBase<UIDispatcher, object[], string>
{
    //子类代码里主要是可以扩展
    //观察者代码都封装到了基类中
    //子类主要是针对三个泛型
    //第一个是传本类,然后本类就是一个单例类了
    //第二个是通知的参数类型
    //第三个是观察者的类型(可以是商品,人,或者"我")就是字典中键的类型
}

添加观察者
添加观察者

移除观察者
移除观察者
在回调函数中写具体的执行事件(立马看/无视它/等有空了看…)

通知观察者
通知观察者
关注了我的人就都收到我的更新文章通知了,也就是执行你传入的那个委托函数,做你该做的事情了

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值