c# - 单一职责 vs 封装

标签 c# encapsulation solid-principles single-responsibility-principle

我正在尝试更多地了解单一职责。如果我尝试代表一个可以添加、删除、更新、检索的客户,那么在过去,我的客户类将拥有所有添加、删除、更新和获取方法。这有助于将现实世界中的客户行为封装在一个类中。由于单一职责,我是否最终将我的客户类分解为 AddCustomer 类、删除客户类、更新客户类和获取客户类,甚至可能获取所有客户类?

最佳答案

在您所描述的场景中,您不需要将您的 Customer 类分解为多个添加/更新/删除客户类 - 事实上,这几乎肯定会使您的系统更难理解.

Incidentally, and I could be wrong, it sounds like you are using something like the Active Record pattern; there is nothing wrong with this pattern per-se, but it is a violation of SRP and it's not the most testable of patterns so I would be inclined to recommend you take an alternative approach.

单一职责原则

SRP 规定一个类(class)应该有一个,而且只有一个,改变的理由。但是,如果您考虑一下您目前拥有的东西,您的Customer已经有两个职责,因此已经有两个可能的原因需要更改

  • 在您正在实现的任何应用领域中代表客户的数据和行为
  • 保留自己的数据(即所有 CRUD 操作)。

因此,如果底层数据库发生变化,您需要更新处理持久性的 Customer 类方法,如果 Customer 所需的行为发生变化,您必须更新 Customer 类以实现新行为。

如何帮助

当您遇到这种情况时,您的 Customer 类总是有可能以混合代码结束,这些代码将业务逻辑和数据库持久性逻辑缠绕成高度耦合的困惑,这样以后你会发现很难在不引起另一方面问题的情况下对一个方面进行更改。 我去过那里,但并不好玩,所以请记住这一点;这就是 SRP 的全部意义所在 - 避免经典的“Big Ball of Mud”情况。

从这里去哪里

  • 如果你真的想关注 SOLID 中的“S” * 那么我建议从 Repository 之类的东西开始模式来处理 Customer 类进出数据库的实际持久性(您创建的 Repository 类本身当然会遵守 SRP,因为它只关心 CRUD到数据库并且不包含任何与 Customer
  • 相关的“业务逻辑”
  • 一旦您对这种方法感到满意,如果您愿意,您可以继续使用类似 Command 的方法模式,一个很好的例子是 here您可以阅读有关 Query 的信息模式在这里(你需要两者)。但是一个漂亮、简单的 Repository 模式也没有错。

*这可能不是可以绝对证明的东西,但我个人发现坚持 SOLID 原则的代码往往非常可测试,非常容易理解和更改,并且非常健壮。再一次,这就是我,所以 YMMV!

关于c# - 单一职责 vs 封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28651947/

相关文章:

c# - Visual Studio - 以编程方式获取启动项目

c# - 使用 RegEx 搜索特定的 try/catch block

c - C语言中如何处理同名函数

c# - 我应该违反 SOLID 中的 S 还是应该违反 DRY 原则?

oop - 省略 super() 和/或 *weakening* 前提条件是否违反里氏替换原则?

c# - SOLID 开闭原则如何与依赖注入(inject)和依赖倒置相适应

c# - 如何使用 MVVM light 处理 WP 8.1 上的后退按钮?

c# - UltraGrid 过滤器单元格属性

c++ - 在类中封装多个 if 语句的最简单方法?

javascript - 避免在 CMS 的所有页面上使用 jQuery 中的全局上下文