技术开发 频道

浅析Web Service模式中的Service Observer

最基本的Subject-Observer关系

说明:

•与经典的Subject不同,为了简化具体每个ConcreateSubject、ConcreateObserver的实现工作量,增加了SubjectBase和ObserverBase两个抽象基类。

•在Subject实际发送通知前,需要每个Observer把自己通过Attach方法注册到Subject中,Subject根据State的变化,对Observer作组播。

•但这个结构仅仅适合进程内调用,在跨进程、跨网络、甚至是Web Service调用中需要增加一些角色,完成分布式的调用。

示例

///C# Observer namespace VisionTask.Training.ServicePattern.ServiceObserver { /// <summary> /// 抽象Observer接口 /// </summary> public interface IObserver<T> { T Data { get;} void Update(T data); } public abstract class ObserverBase<T> : IObserver<T> { protected T data; public virtual void Update(T data) { this.data = data; } public virtual T Data { get { return data; } } } } ///C# Subject using System; using System.Collections.Generic; namespace VisionTask.Training.ServicePattern.ServiceObserver { /// <summary> /// 抽象Subject接口 /// </summary> public interface ISubject<T> { IList<IObserver<T>> Observers { get;} void Attach(IObserver<T> observer); void Detach(IObserver<T> observer); T State { get;set;} void Notify(); } /// <summary> /// 为了简化实体Subject开发量增加的抽象基类 /// </summary> public abstract class SubjectBase<T> : ISubject<T> { protected IList<IObserver<T>> observers = new List<IObserver<T>>(); protected T state; /// <summary> /// 当前Subject的数据内容 /// </summary> public virtual T State { get { return state; } set { state = value; Notify(); } } /// <summary> /// 所有已经注册到该Subject的Observer列表 /// </summary> public virtual IList<IObserver<T>> Observers { get { return observers; } } /// <summary> /// 注册一个Observer实体 /// </summary> /// <param name="observer"></param> public virtual void Attach(IObserver<T> observer) { if (observers == null) throw new ArgumentNullException("observer"); if (observers.Contains(observer)) throw new DuplicateWaitObjectException("observer"); observers.Add(observer); } /// <summary> /// 反注册一个Observer实体 /// </summary> /// <param name="observer"></param> public virtual void Detach(IObserver<T> observer) { if((observer == null) || (!observers.Contains(observer))) return; observers.Remove(observer); } /// <summary> /// 通知每个Observer最新的State信息 /// </summary> public virtual void Notify() { if (observers.Count == 0) return; foreach (IObserver<T> observer in observers) observer.Update(State); } } } ///C# 测试用的实体Observer(s)和Subject class DoubleDataObserver : ObserverBase<int> { public override int Data{get{return data * 2;}} } class DataPlusOneObserver : ObserverBase<int> { public override int Data{get{return data + 1;}} } class DataSubject : SubjectBase<int> { } ///C# UnitTest using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using VisionTask.Training.ServicePattern.ServiceObserver; namespace VisionTask.Training.ServicePattern.UtilityService.UnitTest.InProcessObserver { [TestClass] public class TestServiceObserver { [TestMethod] public void Test() { ISubject<int> subject = new DataSubject(); IObserver<int> observer1 = new DoubleDataObserver(); IObserver<int> observer2 = new DataPlusOneObserver(); subject.Attach(observer1); subject.Attach(observer2); subject.State = 20; Assert.AreEqual<int>(20 * 2, observer1.Data); Assert.AreEqual<int>(20 + 1, observer2.Data); } } }
0
相关文章