ObjectBuilder技术内幕之一
如果你使用过Enterprise Library 2.0 CTP或者使用过Composite UI Application Block,你一定发现它们中间包含了一个ObjectBuilder的程序集。如果你还不知道它是什么、做什么用、它的内部如何实现的话,那么现在就来听听ObjectBuilder(以下简称OB)讲述它的故事吧。
OB顾名思义就是对象创建器,它诞生于微软公司模式与实践小组,从今年5月开始,几经蜕变,终于形成了如今这个稳定的版本。由于它的表现出色,目前被P&P做为Application Blocks的支持模块,用来负责对象的创建工作。
为什么要用OB? 我们知道,一个对象的创建,最简单的方式就是new一个,而对象销毁的工作在.NET平台上,由CLR的GC负责,正常情况下,不需要我们介入。既然如此,为什么还要专门设计一个庞大的对象创建器呢?别急,听我慢慢道来。当手头的项目越来越大,对象也越来越多,对象之间的交互也越来越复杂,这时,简单的对象创建过程已经渐渐的不能适应这种情况了。比如,对象之间存在着依赖关系,那么对象的创建次序就显得很重要。一个对象被创建,需要哪些条件?在对象销毁方面,也存在的同样的问题,尽管有GC,但是GC收集对象的行为并不是可以预测的。OB就是肩负着这样的使命来到人间,下面我们看看OB究竟是如何实现的,一旦你获得了它内部实现的原理,那么你在你的程序中使用OB将更加的得心应手,哪怕你不使用OB,OB中采用的设计思路和设计模式,也会让你学到许多不可多得的知识。
在讲解OB创建对象的过程之前,我们先来看看OB是管理对象的。(注:OB的大部分设计都是可以扩展的,也就是说如果你觉得某些方面,你的想法比OB更出色,那么你可以用自己设计的部分替换OB的默认实现,要做的就是从OB提供的接口类中派生出你的类。)
定位器(Locator)
在OB中有一个称为定位器的东西,通过定位器,你可以很容易地找到需要的对象。定位器被设计为两种,一种是只读定位器,另一种是读写定位器。他们之间存在的继承的关系,也就是说读写定位器是对只读定位器的扩展。
定位器的结构采用链表结构,每一个节点是一个键值对,用来标识对象的唯一性,使得对象不会被重复创建。定位器的链表结构采用可枚举的接口类来实现,这样我们可以通过一个迭代器来遍历这个链表。同时多个定位器也被串成一个链表。具体地说就是多个定位器组成一个链表,表中的每一个节点是一个定位器,定位器本身又是一个链表,表中保存着多个由键值对组成的对象的节点。
下面我们来看看具体的代码(由于篇幅所限,我们只是展示主要的部分,大家可以对照OB的源码):
public interface IReadableLocator : IEnumerable<KeyValuePair<object, object>>
{
//返回定位器中节点的数量
int Count { get; }
//一个指向父节点的引用
IReadableLocator ParentLocator { get; }
//表示定位器是否只读
bool ReadOnly { get; }
//查询定位器中是否已经存在指定键值的对象
bool Contains(object key);
//查询定位器中是否已经存在指定键值的对象,根据给出的搜索选项,表示是否要向上回溯继续寻找。
bool Contains(object key, SearchMode options);
//使用谓词操作来查找包含给定对象的定位器