7

假设我们正在设计一个执行 CRUD(创建、读取、更新和删除)操作的 UserServiceImpl 类。在我看来,创建、读取、更新和删除是更改类的四个原因。这个类是否违反了单一职责原则?如果它违反了,那么我们应该有四个类,如CreateUserServiceImplReadUserServiceImplUpdateUserServiceImplDeleteUserServiceImpl。有很多课程不是矫枉过正吗?

假设我为创建、读取、更新和删除操作分别定义了 4 个接口,并且我的服务类实现了所有四个接口。现在我只能有一个实现类,但通过分离它们的接口,就应用程序的其余部分而言,我已经解耦了这些概念。这是正确的方法还是您发现其中存在一些问题?

4

3 回答 3

5

这就是我喜欢模式和原则的地方——它们是每个人在软件设计上不同意和同意的一致方式:-)

我的观点是以任何方式构建该类,使其成为可用且易于理解的类 - 取决于该类所在的复杂性和上下文。通过简单的实现和上下文,一个类就可以了。您可以说它确实遵守 SRP,因为它的职责是管理 CRUD 操作。但是如果实现很复杂,或者有很多共享代码适合放在抽象父类中,那么也许 4 个单独的类,每个 CRUD 操作一个更有意义。这完全取决于你如何看待它。

模式和原则是很棒的东西,但是如果使用不当,它们会使一个简单的问题变得像没有它们一样复杂。

于 2010-04-15T08:03:21.097 回答
2

在我看来,创建、读取、更新和删除是更改类的四个原因。

为什么?

如果我有一门课Stack,课程是否会发生变化?PushPop

我不这么认为。这是人们对堆栈进行的两个标准操作。与 CRUD 一样,它是对数据存储的一组简单、已建立、众所周知的操作。

现在,您的底层存储技术本身就是您的班级发生变化的原因。也就是说,如果您的 CRUD 实现被硬编码为仅适用于 MS SQL 6.0 数据库的特定实例,那么您违反了 SRP,并且该类将不容易重用或可扩展。

关于 4 个接口,更接近于另一个 SOLID 原则,即ISP,这里的需求取决于您的数据存储的使用模式。例如,如果某些类只需要从数据存储中读取,那么提取仅具有 Read 方法的接口并将该接口作为此类方法的参数请求是完全有意义的。通过分离此接口,您可以稍后对其进行单独的实现。谁知道呢,也许对于只读客户端,您可以发出更好的优化查询或使用内存缓存,但如果不是 - 您可以将实现此接口的默认数据存储实例传递给它们。

于 2012-02-26T00:09:14.420 回答
1

在服务负责单一类型的数据服务或业务信息之前,不违反单一责任原则。

于 2010-04-15T08:00:48.143 回答