为集合类型封装观察者模式
本文是《设计模式_基于C#的工程化实现及扩展》的读书笔记,部分内容直接引用该书。
以下代码展示的是如何为集合类型封装观察者模式。这样当集合元素增加的时候,通过我们自定义集合类的内部委托,就会通知到每个感兴趣的观察者。回想观察者模式的实现原理。观察者模式就是在被观察者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 }
作者:kissazi2
出处:http://www.cnblogs.com/kissazi2/
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。