你会如何命名一个只完成很小一部分功能的类,例如,使用一个循环支付配置文件并将其标记为“失败”。
将其命名为RecurringPaymentProfileMarkAsFailedService是否正确?我知道这只是一个名字,但我想遵循标准/惯例。这是“服务”类应该做的吗,还是这是一种不同的设计模式?我正在尝试跟进SRP原则的路线,因此,如果我是正确的,那么最终会有许多小班,每个小班专门完成一项任务。我想定义一个正确的命名标准。
发布于 2012-10-27 07:15:11
尽管我从未见过严格的文档记录,但我通常使用“服务”一词来表示处理相关最终用户功能的某个子集的类。
例如,假设我有一个银行帐户系统,我可能有以下服务:
public class AccountService
{
public boolean transfer(Account src, Account dest, double amt) // ....
public Account create(User user, double initAmt) // ...
public void close(Account account) // ...
}因此,用户可以执行的“高级”函数被封装在“我的服务”中。服务将访问数据库,实例化任何帮助器,执行所需的计算等。但就像我说的,这正是我在这个行业中观察到的。
就SRP而言:SRP并不意味着您需要为您想要执行的每个功能创建一个全新的类。您不需要一个类来将一个配置文件标记为失败,另一个类将其标记为成功,另一个类来更改配置文件的名称……
SRP意味着每个类处理“一件事”,但“一件事”可以是一组密切相关的函数。需要考虑的另一个重要的OO设计原则是封装。也就是说,类应该最小化它向客户端公开的内容--只公开其他人需要的内容。如果你有大量的小类来管理一个PaymentProfile的内部状态,那么你就暴露了PaymentProfile的所有细节。我给你举个小例子:
假设您的PaymentProfile对象有一个布尔型isSuccess。然后你的类RecurringPaymentProfileMarkAsFailedService会做类似这样的事情:
public class RecurringPaymentProfileMarkAsFailedService {
public void mark(PaymentProfile profile)
{
profile.setSuccess(false);
}
}酷-一切都运行得很好。现在我们收到一个特性请求,要求PaymentProfile不仅可以有“成功”和“失败”两种状态,而且现在我们还需要支持“InternalError”,这意味着一些内部系统在更新过程中崩溃。我们不能再使用布尔值,因此我们将布尔值isSuccess更改为枚举,该枚举可以是:成功、失败、错误。现在我们必须重构我们的MarkAsFailedService。
这是一个微不足道的重构b/c它只是一个类,但对于一个复杂的类树,这些重构可能会在整个系统中回响。这标志着我透露了太多关于我的PaymentProfile的实现细节。类应该被封装,所以对其实现的更改对其客户端的影响很小或没有影响。
发布于 2012-10-24 17:10:59
好吧,不管怎么说,从你的描述中听起来像是在使用Command设计模式。
通常,当我发现类名称太长时,我会改用包或路径层次结构。在这种情况下,它可能类似于:
包: commands.recurringPaymentProfile
类: MarkAsFailed
所以:我不使用“服务”,而是使用“命令”,然后将适用于recurringPaymentProfile的命令分组到一个包中。
发布于 2012-10-24 17:25:01
我相信我理解SRP的“精神”,但就我个人而言,我认为得出这样的结论有点过头了,即您因此必须为RecurringPaymentProfileService上可能只是一个方法(MarkAsFailed)的东西创建一个单独的类(假设您将此逻辑描述为“功能的一小部分”)。
我认为,当您最终为像这样的长而笨拙的名称而苦苦挣扎时,这是一个信号,表明您在代码结构方面没有在相互竞争的原则之间取得适当的平衡。
我的指导原则是,服务应该尝试遵守SRP,因为它与处理(返回/操作)特定业务实体或流程-例如PaymentProfiles -唯一相关。但我的倾向是,试图将服务的内部拆分到第n级,最终可能会违反一大堆其他原则。
https://stackoverflow.com/questions/13037615
复制相似问题