为了使我的类的任何客户机都更简单,我在一个公共方法中放置了一系列私有方法调用。
然后,客户端调用此方法和run中的所有方法来完成该操作。例如:
public void DoRejection(string comments, string rejectionType)
{
GetPartstoReject();
UpdateRejectedPartsStatus(rejectionType);
RemoveInitiatingRejectionPart();
ClearRejectedPartsData();
CreateNewOpenPart();
SaveRejectionComments(rejectionType, comments);
}我能看到的缺点是单元测试更难,因为每个私有方法都不会单独进行测试(遵循只对公共方法进行单元测试的最佳实践)。
如何更好地设计它以增强可测试性,但仍然使客户端调用变得简单?
发布于 2015-11-14 01:57:47
你有问题了。您可以在测试DoRejection()背后的方法的困难中看到它的一个症状,但这只是问题的症状,而不是问题本身。
根本的问题是,您有一个隐藏顺序耦合的方法。
我的一位同事(前几位雇主)曾说过:
如果在描述该方法时使用“and”一词,则需要将该方法分解为较小的部分。
另一种说法是“您违反了这个方法的单一责任原则”。它做的事情太多了。该方法不只是“拒绝”,而是:
在幕后发生的事情太多了。如果这是事务的一部分,则公开事务。您在隔离测试这些部件时遇到困难的原因是它们不是隔离的。删除被拒绝的部件数据的状态要求删除受尊重的部分。
作为公开这些方法的一部分,一种经典的方法是通过合同强制进行设计。检查先决条件,如果没有满足这些先决条件,则引发错误。
还可以通过返回一个包装基础类的对象并只显示适当的下一个状态来强制执行该序列。
如果您希望能够更新多个部分,但只作为一个提交来进行更新,这将特别有用。
还有其他问题潜入其中,有相应的代码气味。不使用参数(并且不返回值)的方法,特别是在执行顺序耦合时,作为伪全局值对对象状态进行操作。有些方法表示下一种方法所依赖的副作用。这引发了一些关于底层设计的非常严重的问题,并且对他们来说有很强的代码气味。
很难从这一小样本代码中确切说明问题出在哪里,但很明显,该代码所基于的设计基础存在一个重大问题。
https://softwareengineering.stackexchange.com/questions/301034
复制相似问题