我最近正在重构既是命令又是查询方法的方法。
将其分为一个命令方法和一个查询方法后,我发现代码中现在有多个地方可以调用命令,然后从查询中获取值,这似乎违反了DRY原理。
但是,如果我要将通用代码包装到一个方法中,则该方法既是命令又是查询。这可以接受吗?
我最近正在重构既是命令又是查询方法的方法。
将其分为一个命令方法和一个查询方法后,我发现代码中现在有多个地方可以调用命令,然后从查询中获取值,这似乎违反了DRY原理。
但是,如果我要将通用代码包装到一个方法中,则该方法既是命令又是查询。这可以接受吗?
Answers:
我之前从未听说过Command-Query-Separation(CQS),但似乎它与Single Responsibility Principle(SRP)有关,SRP指出理想情况下,一个功能/类只应负责做一件事和一件事。
如果您的命令代码是20行代码,而查询代码是另外30行,并且它们全部在一个函数体中,那么显然您违反了SRP,我也假定CQS,并且这两个逻辑应该彼此分开。
但是,以您的假设示例为例,我很可能会创建一个包装器方法,该方法将您的命令和查询结合在一起,以便在代码的很多地方都不会违反DRY。我也不会认为这是违反SRP(也许是CQS)的,因为包装器仍然只有一个职责:将命令与查询结合起来并创建更易于使用的更高层次的抽象。
我认为包装器方法是完全可以接受的解决方案,为了说明这一点,让我们将您的示例更进一步。如果必须运行2个查询而不是1个查询,然后根据该命令执行命令操作,该怎么办。因此,您的2行代码将是6或8。如果在彼此之间进行一些数据验证/检查,该怎么办,所以现在您有15行代码。您是否会考虑创建一个可以完成所有操作的包装程序,而不是将这15行分散在多个文件中?
DRY更重要,因为它解决了更为根本的需求-避免了多余的有效工作。这是一件基本的事情-不需要成为程序员就可以理解它。
CQS是对不支持跟踪效果的语言难以理解其结果和效果均已执行的代码的一种回应。然而:
无法避免为了获得结果而执行代码的必要性,因为这是从小单元组成大型程序的基础。
也不能避免执行代码以达到其效果的必要性,因为在数学和理论计算机科学之外,运行程序的价值在于它可以为我们做的事。
无法避免在同一代码中产生效果和产生结果的必要性,因为在实践中,我们不仅需要效果,而且还需要结构性。
当然,解决跟踪问题对于无人驾驶的人来说太难了,真正的解决办法是让计算机 帮助我们!跟踪运行时值之间的复杂关系(例如数组索引的有效性)可以说是类似的事情,对于这些异常关系,异常和运行时强制执行的合同构成了(非)解决方案。
总之,诸如CQS之类的“解决方案”仅会妨碍根据基于现实的合理原则设计程序。去干。