4

我最近阅读了一篇文章,描述了他们如何清楚地破坏SRP。现在我完全糊涂了,因为我用 setter 和 getter 编写了很长一段时间的单个类。

另外,我找到了这个,但它与SRP无关

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

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

数据访问 = setter 和 getter

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

如果是这样,那么我们在一个类中有两个不同的职责,从而破坏了SRP


让我们假设一下,为了不破坏 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 真的会破坏SRP吗,它们不应该在任何类中使用吗?

3)如果是这样,依赖注入总是答案吗!?

4

1 回答 1

2

setter 和 getter 会破坏 SRP 吗?

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

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

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

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

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

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

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

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

依赖注入总是答案吗?

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

于 2016-02-14T02:21:32.577 回答