单一责任(SRP)vs不问(TDA)?

emi*_*lly 1 oop single-responsibility-principle tell-dont-ask design-principles

我了解许多设计原则在某些情况下会相互冲突。因此,我们必须权衡它们,看看哪个更有利。直到现在,我才意识到SRP原理,并仅以此为基础进行了很多设计,但在内部,遵循该原理有时会感到不对。现在我开始了解TDA,对此我的感觉得到了更多支持:)

SRP:-对象应该担心自己的关注而不是其他人

TDA:-行为(仅取决于其对象状态)应保留在对象本身内部

示例:- 我有不同的形状,如矩形,正方形,圆形等。现在我必须计算面积。

到目前为止,我的设计是:-我遵循SRP,这里有AreaCalculatorService类,该类将询问形状状态并计算面积。该设计背后的理由是形状不应该担心面积计算,因为它不是形状责任。但是理想情况下,我曾经以为区域计算代码应该驻留在每个形状下,如果出现新形状,就好像在线下一样,我必须修改AreaCalculatorService类(这违反了Open的扩展名和闭合的修改原则(OECM))。但始终优先考虑SRP。好像错了

神话被打破了(至少是我的):-使用TDA,我的感觉是正确的,在这里我不应该询问物体的状态,而要告诉形状以计算其面积。尽管它将违反SRP原则,但将支持OECM原则。正如我所说的那样,设计原则有时会相互冲突,但是我相信行为完全取决于其对象状态,行为和状态应该在一起。

另一个示例:-说我必须计算组织中所有雇员的所有部门的薪水,那么我们应该遵循SRP,SalaryCalculatorService将取决于部门和雇员。

它将询问每个员工的薪水,然后对所有薪水进行汇总。因此,我在这里要求员工的状态,但仍不违反TDA calcSalary不仅取决于每个员工的薪水。

让我知道我对这两个原则的解释是否正确,在第一种情况下应遵循TDA,在第二种情况下应遵循SRP?

Pao*_*nti 5

我认为您对TDA的理解是正确的。SRP的问题在于,以我的经验,这是最容易理解的SOLID原则。SRP说,一个班级只有一个改变的理由。“更改原因”部分通常与“它应该只承担一项责任”,因此“它必须只做一件事情”相混淆。不,不是那样的。
“更改的原因”完全取决于类所在的应用程序的上下文。特别是,它取决于与软件进行交互的参与者,并且将来可能会请求更改。
参与者可能是:为软件付费的客户,普通用户和一些超级用户。将管理应用程序数据库或处理应用程序运行所在的硬件的IT部门的DBA。枚举了软件周围的所有参与者后,为了遵循SRP的要求,您必须以只承担单一职责的方式编写类,因此只有来自一个参与者的请求才需要对类进行一些更改。
因此,我认为您应该遵循TDA,将数据和使用这些数据的行为放入同一对象中。这样,您可以管理对象之间的关系,告诉对象该怎么做,而不是询问数据,从而减少耦合并获得更好的封装。
如上所述,SRP将指导您确定哪些行为属于一个对象,而不是另一行为。