结构型模式篇-组合模式(Composite Pattern)
如果有人用过Enterprise Library2.0,一定在源程序中看到了一个叫做ObjectBuilder的程序集,顾名思义,它是用来负责对象的创建工作的,而在ObjectBuilder中,有一个被称为定位器的东西,通过定位器,可以很容易的找到对象,它的结构采用链表结构,每一个节点是一个键值对,用来标识对象的唯一性,使得对象不会被重复创建。定位器的链表结构采用可枚举的接口类来实现,这样我们可以通过一个迭代器来遍历这个链表。同时多个定位器也被串成一个链表。具体地说就是多个定位器组成一个链表,表中的每一个节点是一个定位器,定位器本身又是一个链表,表中保存着多个由键值对组成的对象的节点。所以这是一个典型的Composite模式的例子,来看它的结构图:

图6
正如我们在图中所看到的,IReadableLocator定义了最上层的定位器接口方法,它基本上具备了定位器的大部分功能。
部分代码:
一个抽象基类ReadableLocator用来实现这个接口的公共方法。两个主要的方法实现代码如下: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);
![]()
//使用谓词操作来查找包含给定对象的定位器
IReadableLocator FindBy(Predicate<KeyValuePair<object, object>> predicate);
![]()
//根据是否回溯的选项,使用谓词操作来查找包含对象的定位器
IReadableLocator FindBy(SearchMode options, Predicate<KeyValuePair<object, object>> predicate);
![]()
//从定位器中获取一个指定类型的对象
TItem Get<TItem>();
![]()
//从定位其中获取一个指定键值的对象
TItem Get<TItem>(object key);
![]()
//根据选项条件,从定位其中获取一个指定类型的对象
TItem Get<TItem>(object key, SearchMode options);
![]()
//给定对象键值获取对象的非泛型重载方法
object Get(object key);
![]()
//给定对象键值带搜索条件的非泛型重载方法
object Get(object key, SearchMode options);
}
public abstract class ReadableLocator : IReadableLocator
{
/**//// <summary>
/// 查找定位器,最后返回一个只读定位器的实例
/// </summary>
public IReadableLocator FindBy(SearchMode options, Predicate<KeyValuePair<object, object>> predicate)
{
if (predicate == null)
throw new ArgumentNullException("predicate");
if (!Enum.IsDefined(typeof(SearchMode), options))
throw new ArgumentException(Properties.Resources.InvalidEnumerationValue, "options");
![]()
Locator results = new Locator();
IReadableLocator currentLocator = this;
![]()
while (currentLocator != null)
{
FindInLocator(predicate, results, currentLocator);
currentLocator = options == SearchMode.Local ? null : currentLocator.ParentLocator;
}
![]()
return new ReadOnlyLocator(results);
}
![]()
/**//// <summary>
/// 遍历定位器
/// </summary>
private void FindInLocator(Predicate<KeyValuePair<object, object>> predicate, Locator results,
IReadableLocator currentLocator)
{
foreach (KeyValuePair<object, object> kvp in currentLocator)
{
if (!results.Contains(kvp.Key) && predicate(kvp))
{
results.Add(kvp.Key, kvp.Value);
}
}
}
}
0
相关文章