zoukankan      html  css  js  c++  java
  • 为集合类型封装观察者模式

    本文是《设计模式_基于C#的工程化实现及扩展》的读书笔记,部分内容直接引用该书。

    image

    以下代码展示的是如何为集合类型封装观察者模式。这样当集合元素增加的时候,通过我们自定义集合类的内部委托,就会通知到每个感兴趣的观察者。回想观察者模式的实现原理。观察者模式就是在被观察者SubjectClass里面记录一个观察者感性趣的消息(在本例中是ObserverableDictionary类中的DictionaryEventArgs),然后通过委托通知多个对象(通知机制的原理其实是通过后期将与SubjectClass内部委托相同方法签名的函数绑定在委托上,这样当委托被调用的时候,绑定在这个委托上的方法一并被调用,实现通知多个观察者的现象)。本本例中,ObserverableDictionary类通过继承接口获得一个封装好的委托属性,通过继承Dictionary类获得字典类型实现的缓冲特性。有了相应的委托和缓冲,在最后面ObserverableDictionary类通过重写父类Dictionary类的Add的方法,在Add方法里面调用类内部定义的一个委托,实现通知多个观察者的效果、

    using System;
    using System.Collections.Generic;
    namespace 
    MarvellousWorks.PracticalPattern.ObserverPattern.ObserverCollection.Simple
    {
        /// <summary>
        /// 用于保存集合操作中操作条目信息的时间参数
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        public class DictionaryEventArgs<TKey, TValue> : EventArgs
        {
         /**
          该类后面作为NewItemAdded 委托的参数。
         **/
    
            private TKey key;
            private TValue value;
    
            public DictionaryEventArgs(TKey key, TValue value)
            {
                this.key = key;
                this.value = value;
            }
    
            public TKey Key { get { return key; } }
            public TValue Value { get { return value; } }
        }
    
        /// <summary>
        /// 具有操作事件的IDictionary<TKey, TValue>接口
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        public interface IObserverableDictionary<TKey, TValue> :
            IDictionary<TKey, TValue>
        {
            //设置一个对外通知的接口
            EventHandler<DictionaryEventArgs<TKey, TValue>>  NewItemAdded { get; set;}
        }
    
        /// <summary>
        /// 一种比较简单的实现方式
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        public class ObserverableDictionary<TKey, TValue> : 
            Dictionary<TKey, TValue>, IObserverableDictionary<TKey, TValue>
        {
           //该类通过继承Dictionary,获得Dictionary的属性和方法
           //通过继承IObserverableDictionary,获得对外通知的委托
            protected EventHandler<DictionaryEventArgs<TKey, TValue>>  newItemAdded;
            public EventHandler<DictionaryEventArgs<TKey, TValue>>  NewItemAdded
            {
                get { return newItemAdded; }
                set { newItemAdded = value; }
            }
    
            /// <summary>
            /// 为既有操作增加事件
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            public new void Add(TKey key, TValue value)//使用new显示说明覆盖父类的方法
            {
            
                base.Add(key, value);//通过调用父类的方法,将key和value写入Dictionnary缓冲
                if (NewItemAdded != null)
                    NewItemAdded(this, new DictionaryEventArgs<TKey, TValue>(key, value));//当集合元素增加时,通过委托实现对外通知
            }
        }
    }
    最后附上单元测试
     
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Diagnostics;
     4 using Microsoft.VisualStudio.TestTools.UnitTesting;
     5 using MarvellousWorks.PracticalPattern.ObserverPattern.ObserverCollection.Simple;
     6 namespace MarvellousWorks.PracticalPattern.ObserverPattern.Test.ObserverCollection.Simple
     7 {
     8     [TestClass]
     9     public class TestObserver
    10     {
    11         string key = "hello";
    12         string value = "world";
    13 
    14         public void Validate(object sender, DictionaryEventArgs<string, string> args)
    15         {
    16             Assert.IsNotNull(sender);
    17             Type expectedType = typeof(ObserverableDictionary<string, string>);
    18             Assert.AreEqual<Type>(expectedType, sender.GetType());
    19             Assert.IsNotNull(args);
    20             expectedType = typeof(DictionaryEventArgs<string, string>);
    21             Assert.AreEqual<Type>(expectedType, args.GetType());
    22             Assert.AreEqual<string>(key, args.Key);
    23             Assert.AreEqual<string>(value, args.Value);
    24             Trace.WriteLine(args.Key + "  " + args.Value);
    25         }
    26 
    27         [TestMethod]
    28         public void Test()
    29         {
    30             IObserverableDictionary<string, string> dictionary =
    31                 new ObserverableDictionary<string, string>();
    32             dictionary.NewItemAdded += this.Validate;
    33             dictionary.Add(key, value);
    34         }
    35     }
    36 }
  • 相关阅读:
    HTML常用标签1
    mysql 多对多拆分成 一对多(学生,选修课,成绩)
    JDBC工具包使用
    类反射,用于JDBC
    JDBC基础语句使用
    关于线程等待、线程唤醒方法的引入
    synchronized站点抢票同步例题
    python-装饰器
    jwt, token, session和cookies
    miniapp之登录、授权和支付
  • 原文地址:https://www.cnblogs.com/kissazi2/p/3033849.html
Copyright © 2011-2022 走看看