我最近看过an article that describes他们如何明显打破 SRP 。现在我完全糊涂了,因为我长时间用限制器和吸气器编写单个课程。
另外,我found this,但它与 SRP无关
嗯,乍一看,getter和setter都没有打破单一责任原则因为它们只有“属于”当前类的逻辑。他们可以访问/编写“服务”一个目的的类成员。细但是等等,让我们首先定义基本术语:
数据访问 =设置者和获取者
数据处理 =数据处理,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。但是在这里我只有一个setter而且只有DA类中的getter。
现在问题:
1)即使我只有一个setter和getter,我是否应该总是创建另一个DA类,以便它不会破坏SRP?
2)setter和getter真的打破 SRP ,它们是否应该在任何一个类中使用?
3)如果是这样,依赖注入总是答案!?
答案 0 :(得分:2)
setter和getters是否打破了SRP?
塞特尔和吸气者不是重点。 SRP的要点是一个班级应该只有一个责任。
代表域对象是一项重大责任。执行此操作的对象通常称为&#34;数据对象&#34;。由于语言设计或惯例,数据对象通常具有setter和getter,但它们本身并不是一个单独的责任;他们只是管道。
将数据对象输入和输出持久存储是另一项重大责任。执行此操作的对象通常称为&#34;数据访问对象&#34; (DAO)。 DAO 也不是数据对象可能不需要它所管理的数据对象类型的属性的setter和getter,尽管我可以想象一个非常可怕的框架需要它们。像DAO一样,其他类型的对象使用数据对象(显示它们,对它们进行序列化和反序列化,对它们执行计算等)并且不是数据对象本身可能不需要设置器和getter镜像数据对象。
因此,设置setter和getter表示您的对象是数据对象。如果它是一个数据对象,并且它也是一个DAO或者还有其他一些重大责任,那么它可能会违反SRP。
旁注:你提到了验证。在典型的应用程序验证中,至少单个数据对象属于数据对象本身,因为表示域对象并强制域对象属性之间的个体正确性和关系几乎是相同的责任。
即使我只有一个setter和getter,我是否应该总是创建另一个DA类?
一般来说,是的。要点不是属性的数量;关键是表示和访问是两个不同的职责,属于不同的类。
典型的应用程序有很多域对象,因此如果将域对象与其访问权限分开是有意义的,那么对所有域对象(甚至是单属性对象)进行一致的操作是有意义的。
依赖注入总是答案吗?
这取决于您的架构和框架。您可能拥有不可变数据对象和DAO,其方法将它们作为参数;那里没有DI(尽管你可以将DAO注入使用它们的更高级别的组件中)。您可能拥有使用数据对象实例化的DAO或具有DAO引用的数据对象(我已经看到但不喜欢的两种模式);你可能需要DI那里。无论哪种方式,它与其余的讨论都没有多大关系。