dependency-injection - setter 和 getter 真的会破坏 SRP 吗?

标签 dependency-injection solid-principles single-responsibility-principle

我最近读了an article that describes他们显然如何打破 建议零售价 .现在我完全糊涂了,因为我用 setter 和 getter 编写了很长一段时间的单个类。

另外,我有 found this , 但与 无关建议零售价

好吧,乍一看,getter 和 setter 都不会破坏 单一责任原则 因为它们具有仅“属于”当前类的逻辑。他们可以访问/写入“服务”单一目的的类成员。美好的。

但是等等,让我们先定义基本术语:

数据访问 = setter 和 getter

数据处理 = 数据处理,CRUD 等操作, 验证等

如果是这样,那么我们在一个类中有两个不同的职责,从而破坏了 建议零售价 .

让我们假设一下,为了不破坏 SRP,我们将在不同的类中定义数据访问和数据操作。

class DA { // <- Data Access
  public string getName() {
      return this.name;
  }

  public string setName(name) {
     this.name = name;
  }
}

class DataHandler {
     public DataHandler(da) { // <- Inject an instance of DA
         this.da = da;
     }

     public bool validate() {
          // validation stuff
     }
}

看起来不错,因为我们没有违反上述 SRP。但是在这里,我在 DA 类中只有一个 setter 和一个 getter。

现在的问题 :

1) 即使我只有一个 setter 和 getter,我是否应该始终创建另一个 DA 类,以免破坏 SRP?

2) setter 和 getter 真的会破坏 建议零售价 ,并且它们不应该在任何类中使用吗?

3) 如果是,是依赖注入(inject) 总是答案!?

最佳答案

setter 和 getter 会破坏 SRP 吗?

Setter 和 getter 不是重点。 SRP 的要点是一个类应该只有一个职责。

表示域对象是一项重大责任。执行此操作的对象通常称为“数据对象”。由于语言设计或约定,数据对象通常具有 setter 和 getter,但它们本身并不是单独的责任;他们只是管道。

将数据对象进出持久存储是另一项重大责任。执行此操作的对象通常称为“数据访问对象”(DAO)。一个不是数据对象的 DAO 可能不需要它管理的数据对象类型的属性的 setter 和 getter,尽管我可以想象一个非常糟糕的框架需要它们。与 DAO 一样,其他类型的对象使用数据对象(显示它们、序列化和反序列化它们、对它们执行计算等)而不是数据对象本身可能不需要反射(reflect)数据对象的 setter 和 getter。

因此,拥有 setter 和 getter 表明您的对象是数据对象。如果它是一个数据对象,并且它也是一个 DAO 或有其他重大责任,它可能确实违反了 SRP。

旁注:你提到了验证。在典型的应用程序验证中,至少单个数据对象属于数据对象本身,因为表示域对象并强制执行域对象属性之间的单个正确性和关系几乎是相同的责任。

即使我只有一个 setter 和 getter,我是否应该始终创建另一个 DA 类?

一般来说,是的。重点不是属性的数量;关键是表示和访问是两个不同的职责,属于不同的类。

典型的应用程序有许多域对象,因此如果将域对象与其访问完全分开是有意义的,那么对所有域对象(甚至是单属性对象)一致地这样做是有意义的。

依赖注入(inject)总是答案吗?

这取决于您的架构和框架。您可能有不可变的数据对象和 DAO,其方法将它们作为参数;那里没有 DI(尽管您可以将 DAO 注入(inject)到使用它们的更高级别的组件中)。您可能拥有使用数据对象或引用 DAO 的数据对象实例化的 DAO(我见过但不喜欢这两种模式);你可能需要 DI 那里。无论哪种方式,它都与其余的讨论没有太大关系。

关于dependency-injection - setter 和 getter 真的会破坏 SRP 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15214497/

相关文章:

php - 拆分一个大的 PHP 类

oop - 在 "real world"中使用单一职责原则

single-responsibility-principle - 违反单一职责原则的最佳例子是什么?

java - 如何使用运行时参数创建原型(prototype)范围的 @Bean?使用 getBean(String name, Object...args)?

android - GoogleApiClient 不得为 null [Awareness API]

unit-testing - 测试驱动开发和开放/封闭原则如何协同工作?

oop - 导数的前置条件/​​后置条件规则

.net - 获取单例实例

language-agnostic - 非类的依赖注入(inject)

python - 使用协程和函数作为 Python 中的方法保持 SOLID 和 DRY