我最简单的ASP.NET MVC 2控制器使用AutoMapper拨打了我的服务层,并将视图模型映射到实体。一切看起来很棒,没有重复的代码。

但是,当我进入我的场景时 相似的 行为我很难平衡单一责任原则(SRP)与不重复(干燥)。一个例子可能是需要添加/编辑车辆,其中共享某些属性/行为,而另一些属性/行为是特定车辆的独特之处。

如果我努力寻找真正薄的控制器(从而尊重单个责任原则),我最终会在视图和控制器中重复代码,并具有较小的变化(标题,现场标签,现场可见性,下拉值,选择标准等)。

如果我努力争取未重复的代码,我最终将太多的逻辑捆绑到单个控制器/视图中,并且会肿。

在控制器 /视图中解决重复代码的一些方法是什么?我不是在谈论可以考虑到存储库的数据库代码。我也不在谈论可以将其纳入服务层的业务逻辑。我正在寻找工具和/或经验规则,可以帮助我在上述情况下提供最佳解决方案。

有帮助吗?

解决方案

你得到:

  • 部分
  • 渲染
  • 动作过滤器
  • 服务层和辅助类别(不是HTMLHELPER)
  • 模型粘合剂
  • 基本控制器
  • 依赖注射

因此,您的视图可以调用类似零件的共享部分/操作,可以通过操作过滤器制备常见数据,数据库访问代码可以隐藏在智能模型活页夹中,或者您可以让孩子控制器覆盖具有特定调整的子控制器。而且,当然还有良好的旧服务层,您只需将通用代码提取到辅助/静态方法中,或者更好地注入特定的实现。

这不是什么新的,同样的旧技巧。

或者,也许您的控制器做得太多了吗?这是上面的东西也有帮助的地方。 ASP.NET MVC具有非常好的工具来隐藏基础架构层代码并将其移开控制器。如果不是基础架构 - 它可能属于域层。您可以使用继承,构图和其他OOP技巧。

具体示例。假设您的控制器应以不同的方式设置一些属性。

  1. 如果主要是格式化或选择要显示的属性,您可以有意见来执行此操作
  2. 您可以拥有您的实体具有虚拟方法 - IE重构代码将决策移至域而不是控制器
  3. 您可以拥有助手ViewDetails类,可以将您的实体带来并根据需要的内容获取数据;这有点肮脏,但有时有用。您将决定委派给另一个“策略”类
  4. 您可以使用操作过滤器将此数据添加到ViewData,也可以调整特定的ViewData.Model类型(查找其某些接口)。
  5. 您可以拥有抽象控制器,儿童将实现详细信息传递给基本构造函数,例如():base(repository => repository.getSpecificdata())

等等。我实际上在适当的地方使用它们。

其他提示

您担心SRP和干燥。它们仅是原则,并不总是正确的。如果SRP和Dry使您的代码更可维护,则它们是好的,但是如果它们妨碍了它们,则忽略它们。 MVC相似。它在简单的小型桌面应用程序中很有用,但不适合Web应用程序。 Web表单对互联网世界要好得多,而MVC是1980年代的东西。

我建议您在这种情况下使用SRP而不是干燥。我写 这里 一个详细的答案。

简而言之,两者都是有助于保持代码可维护的规则。干燥是一种低的抽象水平机制,而SRP是高抽象水平。通过维护应用,高抽象水平结构比低抽象水平更重要。

就您而言,我认为没有必要放弃干燥。

一个例子可能是需要添加/编辑车辆,其中共享某些属性/行为,而另一些属性/行为是特定车辆的独特之处。

在这种情况下,许多设计模式可以帮助。您可以使用装饰器,构图等...与制造商结合使用,用于不同类型的车辆。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top