为集合类型封装观察者模式

本文是《设计模式_基于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 }

 

posted @ 2013-04-21 13:43  陈哈哈  阅读(427)  评论(0编辑  收藏  举报