Oop 如何管理(或消除)并行类层次结构?
我正在设计一个简单的表单创建引擎,在这个引擎中,用户可以使用各种样板字段类型(日期、文本、下拉列表)组合新表单 我决定对域对象(表单字段)进行建模,独立于将用于将这些字段呈现给UI的对象 以下是定义域的契约及其某些专门化的接口:Oop 如何管理(或消除)并行类层次结构?,oop,design-patterns,inheritance,Oop,Design Patterns,Inheritance,我正在设计一个简单的表单创建引擎,在这个引擎中,用户可以使用各种样板字段类型(日期、文本、下拉列表)组合新表单 我决定对域对象(表单字段)进行建模,独立于将用于将这些字段呈现给UI的对象 以下是定义域的契约及其某些专门化的接口: namespace Acme.Core.Domain{ public interface IFormField { bool Visible { get; set; } st
namespace Acme.Core.Domain{
public interface IFormField
{
bool Visible { get; set; }
string Key { get; set; }
event EventHandler<FieldVisibilityChangedEventArgs> VisibilityChanged;
FieldType Type{get;}
void Validate(IEnumerable<ValidationError> errors);
int DataId {get;set;}
}
public interface IDropDownField:IFormField{
IDictionary<string, string> Items { get; set; }
KeyValuePair<string, string> SelectedValue { get; set; }
}
public interface IDateField:IFormField{
DateTime? SelectedDate{get;set}
}
}
虽然这种设计让我可以自由地独立于UI设计域模型,但我还没有找到一种连接和管理这两个层次结构的干净方法。我觉得我应该能够利用泛型将并行类彼此连接起来,但我不太明白这会是什么样子。是否有一种模式可以解决关联问题,或者完全不需要并行类层次结构
编辑:我的UI层引用我的业务层(Core.csproj)。下面是我如何将UI类层次结构连接到域类层次结构的几个示例。这些类型目前不使用泛型,但我觉得它们应该使用泛型
// create concrete instances of IControl based on the the domain object passed in
public interface IControlFactory {
IControl CreateControl(IFormField field);
}
// scrape values form the UI controls and apply them to the appropriate domain object
public interface IFormFieldDataBinder{
void Bind(IFormField field, IControl control);
}
我认为这两个等级之间的差别太小了,你真的应该考虑价值或区别是什么。例如,如果您所考虑的只是拥有多个具有不同呈现形式的dropdownlist控件,那么请自问,如果不是在designer中,您将从何处选择具体控件 也许您的
IDropdownListControl
可以是带有抽象“Render”方法的基类
你的ifformfield
和IControl
非常相似,我看不出你买了什么
特别是IDropDownField
在MVC术语中看起来确实像一个模型对象,它是关于表单实例化时字段将保存的数据。它不是关于表单是如何形成的(您说过它是一个域模型)
是否所有IDropListControls
都应该支持型号IDropDownField
?(在这种情况下,我只需删除IDropDownField
,并直接在IDropListControl
上声明属性)
考虑重用抽象原则。对于您创建的每个接口,您能想到两个实现吗?或者它们真的只是具体的类吗?这两个类的层次结构比我表示的更为不同,我编辑了我的问题以反映这一点。例如,我使用域对象执行数据验证,确定它们是否应可见/隐藏,以及处理其他以业务规则为中心的操作。UI类层次结构只关心如何在特定UI技术中表示一个域对象(即字段)。目前,UI技术是Asp.Net WebControl,但我可以很容易地将其替换为MVC HtmlHelpers。基于这个原因,我认为我无法将这两个家族合并在一起。你如何在最终的申请中将这两个家族合并在一起?UI接口是否会引用域接口?
// create concrete instances of IControl based on the the domain object passed in
public interface IControlFactory {
IControl CreateControl(IFormField field);
}
// scrape values form the UI controls and apply them to the appropriate domain object
public interface IFormFieldDataBinder{
void Bind(IFormField field, IControl control);
}