控制资源争用
按照上面的讨论,为了控制Observer对Subject内容的更新和读取,需要在Subject的SetState部分增加并发控制,示例如下:

///C# ///修改前: [WebMethod] public void SetState(int state) { current = state; Notify(); } ///修改后: private static ReaderWriterLock readerWriterLock = new ReaderWriterLock(); private const int LockTimeout = 2000; private object lockRoot = new object(); [WebMethod] public void SetState(int state) { readerWriterLock.AcquireWriterLock(LockTimeout); try { current = state; Notify(); } finally { readerWriterLock.ReleaseWriterLock(); } }
控制耦合关系
上面的分析中虽然把Subject与具体Observer Web Service Proxy的耦合关系解开,但等于把问题转嫁到Subject Web Service Stub上,为了进一步解耦,考虑通过配置机制,动态装载具体Observer Web Service Proxy的类型信息,示例如下:

说明:
通过增加一个新的NamedObserverCollection完成配置信息的对象化,为了便于Stub的使用,它需要实现IEnumerable、ICollection两个接口。实际使用中可以考虑通过继承System.Collections.Specialized. NameValueCollection实现。
(本文的附件部分有一个如何通过访问配置文件,根据抽象类型动态加载实体类型实例的示范。)
小结///App.Config <?xml version="1.0" encoding="utf-8" ?> <configuration> <configuration> <configSections> <section name ="ServiceObserver" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections> <ServiceObserver> <add key="PlusOne" value="VisionTask.Training.ServicePattern.UtilityService.DoubleDataObserver. DoubleDataObserverService, UtilityService"/> <add key="DoubleData" value="VisionTask.Training.ServicePattern.UtilityService.PlusOneObserver. PlusOneObserverService, UtilityService"/> </ServiceObserver> </configuration> </configuration>
通过上面的示例不难看出Web Service中的Service Observer模式可以比较好的解决1:N的信息更新和数据一致性问题,但由于Web Service的分布式特性,实现上需要在经典的Observer模式上增加专门的机制来间接完成SOAP消息的传递和转发。同时,部署上必须充分考虑Subject与各个Observer的物理位置、进程关系,否则会出现较大的性能问题。
相关文章:
《浅析Web Service数据转换器对象》,
http://tech.it168.com/m/2007-08-15/200708150951837.shtml
《浅析Web Service适配器》
http://tech.it168.com/m/2007-08-07/200708070946609.shtml
《如何实现Web Service设计与整合模式?》
http://tech.it168.com/m/2007-07-23/200707231447484.shtml