DoSomethingToThing(Thing n)vs Thing.DoSomething()

时间:2008-09-16 20:42:13

标签: language-agnostic oop coding-style

哪些因素决定哪种方法更合适?

16 个答案:

答案 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. Thing.DoSomething 是合适的,如果Thing是你的句子的主语。
    • DoSomethingToThing(Thing n)是合适的,如果Thing是你的句子的对象。
    • ThingA.DoSomethingToThingB(ThingB m)是一个不可避免的组合,因为在我能想到的所有语言中,函数属于一个类而不是相互拥有。但这是有道理的,因为你可以有一个主题和一个对象。
  2. 主动语音比被动语音更直接,因此请确保您的句子中的主题不仅仅是“计算机”。这意味着,经常使用表单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

还要记住两种形式中任何一种的调用者。调用者可能是一些其他对象的方法,它确实对你的东西有所作为:)