oop – 告诉,不要求和单一责任 – 用课堂上的数据做新事物

我有一个“告诉,不要问”的情况似乎与“单一责任”原则相冲突.我已经看过关于这个问题的其他讨论,但是还没有能够为这种情况找出最适合面向对象的方法.

我有一个程序读取和操作来自各种来源的数据集合.我创建了一个类来保存和操作数据(“DataSet”类).它包括对数据集执行各种操作的方法,例如比较两个数据集以生成包含差异的新数据集,以及将数据集写入文件.

我现在要对数据集执行一些分析,并将结果输出到报告.我第一次尝试编码,询问数据集从中提取信息,然后构建报告,但这似乎违反了“告诉,不要求”原则.那么,我应该把分析方法放在DataSet类中,并告诉数据集分析自己并生成一个报告?这是否违反了单一责任原则?如果我以后要执行其他类型的分析怎么办 – 通过DataSet类可能会变得非常blo肿,有很多不同的分析程序,这与它的核心目的无关.

任何人都可以建议最好的方法吗?有没有一个特殊的设计模式来解决这个问题?

每当设计软件时,您都必须平衡不同的原则,因为它们中的许多原则相互冲突.例如,DRY(Do not Repeat Yourself)原则往往与单一责任原则相冲突,特别是当两件事情相似但并不完全一样的时候.

通常你必须决定哪个原则比较重要,并强调这个原则超过另一个原则(尽管你应该尝试尽可能多的遵守).通常情况下,原则在一起工作,有时他们会相互作用.

在这种情况下,告诉不要问其他原则,如Law of Demeter(尽管它的名称仍然是一个原则,就软件而言,更好地描述为最不了解的原则).

LoD告诉我们的是,一个对象的方法只能调用其他方法

>自己
>作为参数传入的对象
>通过参数传递的对象创建/实例化的任何对象
>对象直接组件对象
>或全局变量

没有具体说明,但是我觉得选择方法调用的优先级顺序应该是顺序的,全局变量是最后的.但是,这不是在这里和那里.

所以,如果我们结合Tell,不要询问与LoD,那么将对象传递给另一个“询问”对象是完全可以的.意思是说,你有一个Analysis对象,你可以“告诉”做某事,把DataSet对象作为参数传递.那就是TDA.在Analysis对象的方法中,您只需访问“亲密的朋友”数据即可遵守LoD.

这也符合SRP,因为您的DataSet仍然只是一个DataSet,而您的Analysis对象是一个Analysis对象.

这里的关键是这些原则往往是“相对论”的.这意味着,从获取数据并希望执行分析的父对象的角度来看,您正在“告诉”分析对象来做某事.

TDA的目的是您的父代码不应该查询您的DataSet的状态,然后根据此做出决定.它应该将对象传递给其他对象,并让这些对象履行其职责,这可能包括将这些对象查询到其状态,但这是可以的,因为它是在其责任的上下文中.

进一步参考:

http://pragprog.com/articles/tell-dont-ask

编辑:

如果你想要一个更权威的来源,那么没有比Martin Fowler自己更好的(最终读到你会发现这个评论)

http://martinfowler.com/bliki/TellDontAsk.html

But personally,I don’t use tell-dont-ask. I do look to co-locate data and behavior,which often leads to similar results. One thing I find troubling about tell-dont-ask is that I’ve seen it encourage people to become GetterEradicators,seeking to get rid of all query methods. But there are times when objects collaborate effectively by providing information. A good example are objects that take input information and transform it to simplify their clients,such as using EmbeddedDocument. I’ve seen code get into convolutions of only telling where suitably responsible query methods would simplify matters 07003. For me,tell-don’t-ask is a stepping stone towards co-locating behavior and data,but I don’t find it a point worth highlighting

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...