哪些因素决定哪种方法更合适?
答案 0 :(得分:14)
我认为他们都有自己的位置。
您不应仅仅因为您认为“功能编程很好”而使用DoSomethingToThing(Thing n)
。同样,您不应该简单地使用Thing.DoSomething()
,因为“面向对象的编程很好”。
我认为这取决于你想传达的内容。不要再将代码视为一系列指令,而是开始将其视为故事的段落或句子。从手头的任务角度考虑哪些部分是最重要的。
例如,如果您想要强调的“句子”部分是对象,则应使用OO样式。
示例:
fileHandle.close();
大多数情况下,当您传递文件句柄时,您正在考虑的主要事情是跟踪它所代表的文件。
反:
string x = "Hello World";
submitHttpRequest( x );
在这种情况下,提交HTTP请求远比正文字符串重要,因此submitHttpRequst(x)
优于x.submitViaHttp()
毋庸置疑,这些并非相互排斥。你可能实际上有
networkConnection.submitHttpRequest(x)
将两者混合在一起。重要的是你要考虑哪些部分被强调,以及你将如何传达给未来的代码读者。
答案 1 :(得分:8)
要面向对象,请不要问:http://www.pragmaticprogrammer.com/articles/tell-dont-ask。
所以,Thing.DoSomething()而不是DoSomethingToThing(Thing n)。
答案 2 :(得分:3)
如果你正在处理事物的内部状态,那么Thing.DoSomething()更有意义,因为即使你改变Thing的内部表示,或者它是如何工作的,与它交谈的代码也不必更改。如果你正在处理一系列事物,或者编写一些实用方法,程序风格的DoSomethingToThing()可能更有意义或更直接;但是,通常可以表示为表示该集合的对象上的方法:例如
GetTotalPriceofThings();
VS
Cart.getTotal();
这实际上取决于代码面向对象的方式。
答案 3 :(得分:3)
主动语音比被动语音更直接,因此请确保您的句子中的主题不仅仅是“计算机”。这意味着,经常使用表单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);
答案 4 :(得分:1)
我同意猎户座的观点,但我会重新考虑决策过程。
你有一个名词,一个动词/一个对象和一个动作。
我喜欢文件/字符串示例。有许多字符串操作,例如“SendAsHTTPReply”,这对于您的平均字符串不会发生,但确实经常在某个设置中发生。但是,你基本上总是会关闭一个文件(希望如此),所以将Close动作放在类接口中是完全合理的。
另一种思考方式是购买娱乐系统的一部分。将电视遥控器与电视捆绑在一起是有意义的,因为您总是一起使用它们。但是将特定录像机的电源线与电视捆绑在一起会很奇怪,因为许多客户永远不会使用它。关键的想法是此操作在此对象上的使用频率?
答案 5 :(得分:0)
这里的信息不够充分。这取决于您的语言是否支持构造“Thing.something”或等效(即它是OO语言)。如果是这样,那就更合适了,因为这是OO范例(成员应该与他们所处理的对象相关联)。当然,在程序风格中,DoSomethingtoThing()是您唯一的选择......或者ThingDoSomething()
答案 6 :(得分:0)
DoSomethingToThing(Thing n)将更多地是一种功能性方法,而Thing.DoSomething()将更像是一种面向对象的方法。
答案 7 :(得分:0)
这是面向对象与程序编程的选择:)
我认为有良好记录的OO优势适用于Thing.DoSomething()
答案 8 :(得分:0)
答案 9 :(得分:0)
以下是需要考虑的几个因素:
Thing
课程。如果没有,请使用前者Thing
实例化。如果没有,请将后者用作静态方法Thing
实际上被修改(即具有更改的属性),则更喜欢后者。如果Thing
未被修改,则后者同样可以接受。答案 10 :(得分:0)
即使你没有使用OO语言,你也可以使用Thing.DoSomething(),为了你的代码的整体可读性,有一组函数,如:
ThingDoSomething() ThingDoAnotherTask() ThingWeDoSomethingElse()
然后
AnotherThingDoSomething()
等等要好得多。
所有适用于“Thing”的代码都在一个位置。当然,“DoSomething”和其他任务应该一致地命名 - 所以你有一个ThingOneRead(),一个ThingTwoRead()...到现在你应该得到点。当你在十二个月的时间内回到代码上工作时,你会感激花时间把事情弄清楚。
答案 11 :(得分:0)
一般来说,如果“某事”是“事物”自然知道该怎么做的动作,那么你应该使用thing.doSomething()。这是很好的OO封装,因为否则DoSomethingToThing(thing)必须访问“thing”的潜在内部信息。
例如invoice.getTotal()
如果“某事物”自然不是“事物”领域模型的一部分,那么一种选择就是使用辅助方法。
例如:Logger.log(发票)
答案 12 :(得分:0)
如果对某个对象做“SomeSomething”可能会在另一个场景中产生不同的结果,那么我建议你使用oneThing.DoSomethingToThing(anotherThing)。
例如,您可能有两个在程序中保存的东西,因此您可能采用DatabaseObject.Save(thing)SessionObject.Save(thing)比thing.Save()或thing.SaveToDatabase或thing更有利。 SaveToSession()。
除非我正在检索公共属性,否则我很少将参数传递给类。
答案 13 :(得分:0)
要添加Aeon的答案,这取决于事物以及你想对它做些什么。因此,如果您正在编写Thing,而DoSomething会改变Thing的内部状态,那么最好的方法就是Thing.DoSomething。但是,如果动作不仅仅是改变内部状态,那么DoSomething(Thing)更有意义。例如:
Collection.Add(Thing)
优于
Thing.AddSelfToCollection(Collection)
如果你没有写Thing,并且不能创建派生类,那么你没有chocie但是做DoSomething(Thing)
答案 14 :(得分:0)
即使在面向对象的编程中,使用函数调用而不是方法(或者调用除我们调用它之外的对象的方法)也是有用的。想象一个简单的数据库持久性框架,您只想在对象上调用save()。而不是在您希望保存的每个类中包含SQL语句,从而使代码复杂化,在整个代码中传播SQL并将存储引擎更改为PITA,您可以创建一个定义保存的接口(Class1),保存(Class2) )等及其实施。然后你实际上是在调用databaseSaver.save(class1)并将所有内容放在一个地方。
答案 15 :(得分:0)
我必须同意Kevin Conner
还要记住两种形式中任何一种的调用者。调用者可能是一些其他对象的方法,它确实对你的东西有所作为:)