DoSomethingToThing(事物n)vs Thing.DoSomething()
哪些因素决定哪种方法更合适?
解决方案
回答
这里没有足够的信息。这取决于语言是否支持" Thing.something"或者等效结构(即,这是一种OO语言)。如果是这样,则它更合适,因为那是OO范式(成员应与其作用的对象相关联)。当然,以程序化方式,DoSomethingtoThing()是我们唯一的选择...或者ThingDoSomething()
回答
要面向对象,请不要问:http://www.pragmaticprogrammer.com/articles/tell-dont-ask。
因此,使用Thing.DoSomething()而不是DoSomethingToThing(Thing n)。
回答
DoSomethingToThing(Thing n)更像是一种功能性方法,而Thing.DoSomething()更像是一种面向对象的方法。
回答
那就是面向对象与过程编程的选择:)
我认为,有据可查的OO优势适用于Thing.DoSomething()
回答
如果我们正在处理事物的内部状态,那么Thing.DoSomething()会更有意义,因为即使我们更改Thing的内部表示形式或者它的工作方式,与之对话的代码也不必更改。如果我们正在处理事物的集合,或者正在编写一些实用程序方法,则程序样式的DoSomethingToThing()可能更有意义或者更直截了当;但仍然可以将其表示为表示该集合的对象上的方法:例如
GetTotalPriceofThings();
与
Cart.getTotal();
这实际上取决于代码面向对象的方式。
回答
有人问过这个设计问题:电话是拨电话号码,还是电话号码在电话上拨号?
回答
这里有几个要考虑的因素:
- 我们可以修改或者扩展Thing类吗?如果不是,请使用前者
- 可以实例化"事物"。如果不是,请使用后面的方法作为静态方法
- 如果实际更改了"事物"(即属性发生了变化),请选择后者。如果未修改"事物",则后者也是可以接受的。
- 否则,由于对象是要映射到现实世界对象的,因此请选择看起来更现实的方法。
回答
即使我们不是使用OO语言工作,也要使用Thing.DoSomething()来确保代码的整体可读性,并且具有以下一组函数:
ThingDoSomething()
ThingDoAnotherTask()
ThingWeDoSomethingElse()
然后
AnotherThingDoSomething()
等等要好得多。
所有适用于"事物"的代码都在一个位置上。当然," DoSomething"和其他任务的名称应保持一致,因此我们现在有了ThingOneRead(),ThingTwoRead()...。当我们在十二个月的时间里重新使用代码时,我们将不胜感激,抽出宝贵的时间使事情变得合乎逻辑。
回答
通常,如果"事物"是"事物"自然知道如何做的动作,则应使用thing.doSomething()。这是很好的OO封装,因为否则DoSomethingToThing(thing)必须访问" thing"的潜在内部信息。
例如invoice.getTotal()
如果"某物"不是"物"域模型的自然组成部分,则一种选择是使用辅助方法。
例如:Logger.log(发票)
回答
如果对对象执行DoingSomething可能在另一种情况下产生不同的结果,那么我建议我们使用oneThing.DoSomethingToThing(anotherThing)。
例如,我们可能有两个目的是在程序中保存东西,因此我们可以采用DatabaseObject.Save(thing)SessionObject.Save(thing)比thing.Save()或者thing.SaveToDatabase或者thing.SaveToSession()更有利。 。
除非检索公共属性,否则很少给类传递任何参数。
回答
要添加到Aeon的答案中,这取决于事物和我们要对此做的事情。因此,如果我们正在编写Thing,而DoSomething会改变Thing的内部状态,那么最好的方法就是Thing.DoSomething。但是,如果操作不仅仅改变内部状态,那么DoSomething(Thing)更有意义。例如:
Collection.Add(Thing)
胜过
Thing.AddSelfToCollection(Collection)
如果我们没有编写Thing,并且无法创建派生类,那么我们就别无选择,只能执行DoSomething(Thing)
回答
我认为两者都有自己的位置。
我们不应仅仅因为认为"函数式编程是好的"就使用DoSomethingToThing(Thing n)。同样,我们不应该简单地使用Thing.DoSomething(),因为"面向对象编程是好的"。
我认为这取决于我们要传达的内容。不再将代码视为一系列指令,而开始像故事的段落或者句子那样思考代码。从当前任务的角度考虑哪些部分最重要。
例如,如果我们想强调的"句子"部分是对象,则应使用OO样式。
例子:
fileHandle.close();
在大多数情况下,当我们传递文件句柄时,我们考虑的主要内容是跟踪它所代表的文件。
反例:
string x = "Hello World"; submitHttpRequest( x );
在这种情况下,提交HTTP请求比作为主体的字符串重要得多,因此,submitHttpRequst(x)
比x.submitViaHttp()
更可取。
不用说,这些不是相互排斥的。你可能实际上有
networkConnection.submitHttpRequest(x)
我们将两者混合在一起。重要的是,我们需要考虑强调哪些部分,以及将传达给将来的代码读者的内容。
回答
- ThingA.DoSomethingToThingB(ThingB m)是不可避免的组合,因为在我能想到的所有语言中,函数都属于一个类,而不是相互拥有的。但这是有道理的,因为我们可以有一个主题和一个对象。
主动语音比被动语音更直接,因此请确保句子所包含的主题不只是"计算机"。这意味着,经常使用表格1和表格3,而很少使用表格2.
为了清楚起见:
// Form 1: "File handle, close." fileHandle.close(); // Form 2: "(Computer,) close the file handle." close(fileHandle); // Form 3: "File handle, write the contents of another file handle." fileHandle.writeContentsOf(anotherFileHandle);
回答
即使在面向对象的程序设计中,使用函数调用代替方法(或者为此调用对象的方法而不是我们调用它的方法)也可能有用。想象一个简单的数据库持久性框架,我们只想在一个对象上调用save()。我们可以创建一个定义save(Class1),save(Class2)的接口,而不是在要保存的每个类中都包含SQL语句,从而使代码复杂化,在整个代码中分布SQL,并使存储引擎变为PITA, )等及其实现。然后,我们实际上将调用databaseSaver.save(class1)并将所有内容放在一个地方。
回答
我必须同意凯文·康纳(Kevin Conner)
还要记住两种形式的调用者。调用者可能是某些其他对象的方法,该对象肯定会对事物产生作用:)
回答
我同意Orion的意见,但我将重述决策过程。
我们有一个名词和一个动词/一个对象和一个动作。
- 如果许多此类对象将使用此操作,请尝试使该操作成为对象的一部分。
- 否则,请尝试将操作与相关操作分开进行分组。
我喜欢File / string的例子。有许多字符串操作,例如" SendAsHTTPReply",它不会在普通字符串中发生,但通常会在特定设置下发生。但是,基本上,我们总是会(希望)关闭一个文件,因此将Close动作放在类接口中非常有意义。
另一种思考方式是购买娱乐系统的一部分。将电视遥控器与电视捆绑在一起是有意义的,因为我们始终将它们一起使用。但是将特定VCR的电源线与电视捆绑在一起是很奇怪的,因为许多客户永远不会使用它。关键思想是在此对象上多久执行一次此操作?