ASP.NET MVC - when SRP and DRY appear to conflict
我最简单的ASP.NET MVC 2控制器调用服务层,并使用AutoMapper将视图模型映射到实体。一切看起来都很棒,没有重复的代码。
但是,当我遇到行为类似的场景时,我很难在"单一职责原则"(SRP)和"不要重复自己"(DRY)之间取得平衡。例如,可能需要添加/编辑载具,其中某些属性/行为是共享的,而另一些则是特定载具所独有的。
如果我追求真正的瘦控制器(因此遵循单一职责原则),那么最终我会在视图和控制器中都重复代码,而这些代码会有微小的变化(标题,字段标签,字段可见性,下拉值,选择标准等)。
如果我努力争取不重复的代码,最终我将太多的逻辑捆绑到一个控制器/视图中,结果就会肿。
解决控制器/视图中重复代码的一些方法是什么?我不是在谈论可以分解到存储库中的数据库代码。我也没有在谈论可以分解到服务层的业务逻辑。我正在寻找工具和/或经验法则,以帮助我在上述情况下提供最佳解决方案。
你得到:
- 部分
- RenderAction
- 动作过滤器
- 服务层和帮助程序类(不是HtmlHelper)
- 模型粘合剂
- 基本控制器
- 依赖注入
因此,您的视图可以调用相似零件的共享部分/动作,可以通过动作过滤器准备通用数据,可以将数据库访问代码隐藏在智能模型绑定程序中,也可以让父控制器通过特定的调整来覆盖子控制器。当然,还有很好的旧服务层,您只需在其中将通用代码提取到辅助/静态方法中,或者更好地注入特定的实现。
没什么新的,同样的老把戏。
或者,也许您的控制器执行了太多工作?这就是上面的内容也有帮助的地方。 ASP.NET MVC有很好的工具来隐藏基础结构层代码并将其从控制器移开。如果它不是基础架构,则可能属于域层。在那里,您可以使用继承,组合和其他OOP技巧。
具体的例子。假设您的控制器应以其他方式设置一些属性。
等等。我实际上在适当的地方使用了它们。
在这种情况下,建议您在SRY上使用SRP。我在这里写了详细的答案。
简而言之,这两个都是有助于保持代码可维护性的规则。 DRY是低抽象级别的机制,而SRP是高抽象级别。通过维护应用程序,高抽象级别结构比低抽象级别更重要。
在您的情况下,我认为没有必要放弃DRY。
An example of this might be the need to add/edit vehicles where some
properties/behaviors are shared while others are unique to a specific
vehicle.
在这种情况下,许多设计模式都可以提供帮助。您可以将装饰器,构图等...与用于不同类型车辆的构建器结合使用。
您太担心SRP和DRY了。它们只是原则,并不总是正确的。如果SRP和DRY可以使您的代码更具可维护性,则它们很好,但是如果它们妨碍了您,请忽略它们。 MVC与此类似。它在简单的小型桌面应用程序中很有用,但不适用于Web应用程序。 Web窗体对Internet世界来说要好得多,而MVC是1980年代的东西。