构建可插入的解析器组件 - Builder 模式 (C#)






1.67/5 (8投票s)
一种用于实现可插入解析器组件的设计模式,它体现了以下 GRASP 模式 - 创建者、低耦合、高内聚、多态、封装变化。
引言
设计模式属于以下三种类型之一
- 创建型
- 结构型
- 行为型
创建型模式处理对象创建过程。它基本上使系统独立于对象的创建、组合和表示方式。这种配置可以是编译时或运行时。因此,它们被进一步归类为类或对象创建型模式。
类模式处理通过继承建立的子类关系。这些关系是静态的,即在编译时固定。对象模式处理可以在运行时更改的对象关系,并且更加动态。类创建型模式将对象创建的责任推迟给子类,而对象创建型模式将责任推迟给另一个对象。类创建型模式使用继承来更改要实例化的类,而对象创建型模式将实例化委托给另一个对象。
生成器模式是一种对象创建型模式。
问题
需要构建支持复杂解析逻辑的中间层组件。数据对象(类型化数据集)由 UI 组件更新。从主交易中添加和删除数据元素应最小化并隔离对中间层组件的影响。因此,需要使用一种设计模式来
- 将复杂对象的构建过程与其组成部分分离开来。
- 定义一个必须允许对象不同表示的构建过程。
- 通过构建一个具体的生成器,为新的主交易提供一个可扩展的框架,并且应该是可插入的。
解决方案
生成器模式用于通过一个源对象(类型化数据集)创建各种复杂对象。生成器对象持有一个类型化数据集,该数据集通过抽象生成器类(UpdateBufferBuilder
)的一组通用接口调用,独立地为每个复杂对象(DfhCommArea
)的创建做出贡献。
需要一个导演对象来选择生成器类。抽象生成器类将是接口调用的列表 - 例如 BuildDfhCommArea()
- 导演将使用这些调用。每个具体的生成器类都可以为这些调用实现一个方法。
/// <summary>
/// Director Class, Director Object
// </summary>
public class UpdateBufferDirector
{
public DfhCommArea Construct(
UpdateBufferBuilder updateBufferBuilder )
{
return updateBufferBuilder.BuildDfhCommArea();
}
}
/// <summary>
/// Abstract Builder Class
/// </summary>
public abstract class UpdateBufferBuilder
{
public abstract DfhCommArea BuildDfhCommArea();
}
/// <summary>
/// Concrete Builder Class
/// </summary>
public class UpdateBuffer220Builder : UpdateBufferBuilder
{
//Source Object : Typed Dataset
private Buffer220 _buffer220;
public UpdateBuffer220Builder()
{
_buffer220 = new Buffer220();
}
public void FetchSchema(ref DataSet pbuffer220)
{
pbuffer220 = _buffer220;
}
public override DfhCommArea BuildDfhCommArea()
{
//Parse the data in TypedDataSet
string BufferData = string.Empty;
//Iterate through the Tables
//of the Typed dataset and form the BufferData
//Construct the Product
DfhCommArea dfhCommArea = new DfhCommArea();
dfhCommArea._functionCode = 220;
dfhCommArea._dfhCommAreaLayout = BufferData ;
return dfhCommArea;
}
}
/// <summary>
/// Concrete Builder Class
/// </summary>
public class UpdateBuffer250Builder : UpdateBufferBuilder
{
//Source Object : Typed Dataset
private Buffer250 _buffer250;
public UpdateBuffer250Builder()
{
_buffer250 = new Buffer250();
}
public void FetchSchema(ref DataSet pbuffer250)
{
pbuffer250 = _buffer250;
}
public override DfhCommArea BuildDfhCommArea()
{
//Parse the data in TypedDataSet
string BufferData = string.Empty;
//Iterate through the Tables
//of the Typed dataset and form the BufferData
//Construct the Product
DfhCommArea dfhCommArea = new DfhCommArea();
dfhCommArea._functionCode = 250;
dfhCommArea._dfhCommAreaLayout = BufferData ;
return dfhCommArea;
}
}
/// <summary>
/// Product
/// </summary>
public class DfhCommArea
{
public int _functionCode;
public string _dfhCommAreaLayout;
public DfhCommArea GetDfhCommArea()
{
return this;
}
}
示例
类型化数据集由 UI 填充。业务规则可以应用于此数据,由业务对象来完成,在这种情况下,序列图中描绘的客户端将是业务对象的一部分。构建过程将是相同的,但会根据功能码的不同而有所不同。每个功能码对应一个不同的主交易。因此,任何新交易都应该是可插入的,只需定义另一个生成器类即可。
静态视图
包含关系组合显示在
- 导演和抽象生成器类之间
- 类型化数据集和具体生成器类之间
动态视图
- 创建 表示构造函数。
Buffer220
是一个保存数据的类型化数据集。UpdateBuffer220Builder
是具体生成器类,它持有一个Buffer220
的实例。dfhCommArea
是一个复杂对象。
GRASP 模式
支持以下 GRASP 模式
- 创建者:生成器类负责
DFHCommArea
对象的创建和更新,因为它们了解要分配的功能码和dfhCommArea
的布局。 - 低耦合:通过将责任分配给正确的类。类型化数据集是生成器类的一部分,而不是导演类的一部分,因为它负责读取模式元素和数据并形成
dfhCommArea
。 - 高内聚:通过将职责分布到适当的类。解析逻辑是生成器类的职责;导演的职责是选择合适的生成器类。
- 信息专家:将职责分配给拥有履行职责所需信息的类。
- 多态:通过展示可插入的软件组件。支持新的主交易意味着构建新的生成器类。这些可以被集成,而无需更改源代码或导演对象。
- 封装变化:由于主交易的变化导致
dfhCommArea
的变化只会影响特定的生成器类,这些类负责解析逻辑,而不会影响导演或dfhCommArea
对象。