应用Composite模式
在ESFramework 4.0 进阶(02)-- 核心:消息处理的骨架流程一文中我们介绍的ESFramework提供的消息处理的骨架流程,假设我们有这样的需求,我们需要在网关级消息监控器处放置两个监控器,一个用于对收到的消息进行特殊的验证,另一个用于检查重复的消息。咋一看,可能觉得骨架流程做不到这一点,因为它只为网关级监控器预留了一个位置,没有办法将两个网关级监控器挂接到这一个位置上。
ESFramework通过Composite模式解决了这个问题。Composite模式允许将实现了同一接口的多个组件放在一个容器中,而这个容器也实现了相同的接口。如此,我们可以使用这个容器组件来挂接到只接受单个组件的扩展点。在ESFramework中,将这种容器组件称为ContainerStyle组件。下图是使用Composite模式组合IMessageSpy组件而得到ContainerStyleMessageSpy组件的类图。
ContainerStyleMessageSpy的实现也很简单,代码如下所示:
{
#region SpyList
private IList<IMessageSpy> spyList = new List<IMessageSpy>();
public IList<IMessageSpy> SpyList
{
set
{
spyList = value ?? new List<IMessageSpy>();
}
}
#endregion
#region IMessageSpy 成员
#region Enabled
private bool enabled = true;
public bool Enabled
{
set { this.enabled = value; }
get { return this.enabled; }
}
#endregion
#region SpyMessageReceived
public bool SpyMessageReceived(IMessage msg)
{
if (!this.enabled)
{
return true;
}
foreach (IMessageSpy spy in this.spyList)
{
bool keepOn = spy.SpyMessageReceived(msg);
if (!keepOn)
{
return false;
}
}
return true;
}
#endregion
#region SpyMessageToBeSent
public bool SpyMessageToBeSent(IMessage msg)
{
if (!this.enabled)
{
return true;
}
foreach (IMessageSpy spy in this.spyList)
{
bool keepOn = spy.SpyMessageToBeSent(msg);
if (!keepOn)
{
return false;
}
}
return true;
}
#endregion
#endregion
}
对于上面的例子,我们可以将用于消息验证的监控器和检查重复消息的监控器放到一个ContainerStyle风格的网关级监控器组件ContainerStyleMessageSpy中,然后再将这个ContainerStyleMessageSpy组件挂接到消息流程骨架中对应的扩展点处。
对于消息监控器IMessageSpy、消息过滤器IMessageFilter、消息处理器IMessageProcesser等等,ESFramework都提供了对应的ContainerStyle组件实现,这些组件的名称都以“ContainerStyle”开头。当我们需要将同一类型的多个消息组件组装成一个整体时,可以直接使用这些ContainerStyle组件来进行组装。
关于在设计开发中要不要使用设计模式、使用何种设计模式,其实很多时候都是自然而然水到渠成的事情,并不是要刻意将模式硬搬到我们的项目中。有些时候,不经意间,你也许已经不自觉地使用了某个经典模式,或创造了某个模式。