我当前的应用程序允许用户通过一组管理屏幕定义自定义 Web 表单。它本质上是一个 EAV 类型的应用程序。因此,我无法对 HTML 或 ASP.NET 标记进行硬编码来呈现给定页面。相反,UI 从服务层请求 Form 对象的实例,服务层又使用多个 RDMBS 表构造一个实例。 Form 包含您希望在这种上下文中看到的类:Form
=> IEnumerable<FormSections>
=>IEnumerable<FormFields>
服务层如下所示:
public class MyFormService: IFormService{
public Form OpenForm(int formId){
//construct and return a concrete implementation of Form
}
}
一切都运行良好(暂时)。 UI 并不知道给定表单中存在哪些部分/字段:它很乐意将收到的 Form 对象呈现到功能性 ASP.NET 页面中。
几周后,我收到业务的新要求:当查看表单的不可编辑(即只读)版本时,某些字段值应合并在一起,并应添加其他人为/计算的字段。我说没问题。只需修改我的服务类,使其方法更加明确:
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId){
//construct and a concrete implementation of Form
//apply additional transformations to the form
}
}
再次,一切都运转良好,力量也恢复了平衡。 UI 仍然不知道表单中的内容,并且我们实现了关注点分离。然而仅仅几周后,业务就提出了新的要求:在某些场景下,我们只需要申请some我上面提到的形式转换。
此时,感觉“显式方法”方法已经走进了死胡同,除非我想以方法爆炸结束(OpenFormViewingScenario1、OpenFormViewingScenario2 等)。相反,我引入了另一个间接级别:
public interface IFormViewCreator{
void CreateView(Form form);
}
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId, IFormViewCreator formViewCreator){
//construct a concrete implementation of Form
//apply transformations to the dynamic field list
return formViewCreator.CreateView(form);
}
}
从表面上看,这似乎是可以接受的方法,但也有一定的味道。也就是说,一直对 OpenFormForViewing 的实现细节一无所知的 UI 必须具备 IFormViewCreator 的知识并创建 IFormViewCreator 的实例。
- 我的问题有两个:是否有
更好的方法来实现
我追求的可组合性? (也许通过
使用 IoC 容器或 home
轧制工厂来创建
具体的 IFormViewCreator)?
- 我是否从根本上搞砸了
这里抽象?