2011-12-13 59 views
3

我思考模式,允许我回到这两个计算结果和状态:返回计算结果和状态。最佳实践

有,我能想到的几种方法:

  • 函数返回计算结果,正在返回的状态通过参数(不是所有的语言都支持参数,这看起来是错误的,因为一般来说你不希望参数被修改)。 (缺点是你必须创建仿真类来返回函数结果或使用没有语义含义的对 - 你知道哪个参数是它的顺序)。

  • 如果你的状态就是成功/失败就可以返回计算值,并在错误的情况下抛出异常(看起来像最好的方法,但只有成功/失败情况的工作,不应该被滥用控制正常的程序流程)。

  • 函数返回值,函数参数委托给onSuccess/onFailure过程。

  • 有一个(state-full)方法类有状态字段,并且方法返回计算结果(我更喜欢有无状态/不可变对象)。

请给我利弊和情况使用上述方法或告诉我,我可以使用(最好带提示的先决条件时使用它们)其他模式的先决条件的提示。


编辑: 真实的例子: 我开发的Java EE互联网应用,我有一类解析请求参数字符串转换为他们的一些业务逻辑对象。解析器正在检查db是否正在创建或编辑对象,然后向控制器返回从db中获取的新对象或对象。控制器根据从解析器读取的对象状态(新/编辑)采取行动。我知道这很糟糕,我想在这里改进代码设计。

+0

在C和C++中,至少完全可以拥有out参数。所以我通常通过返回值返回成功/失败,并修改一个输出参数以反映计算输出。这也允许在动态分配内存的情况下更好的资源控制。 – arne

+0

有很多缺点和专业的,但我想知道这个问题是否会保持开放,因为它看起来对我来说是类似于http://stackoverflow.com/questions/36707/should-a-function-have-只有一个回报陈述问题。我希望它保持开放,我认为这些问题完全符合本网站的内容。 –

+0

我认为其他问题与此完全不同。这是关于在代码中使用多个return语句,而不是返回多个“结果”。另外我发现这个:http://stackoverflow.com/questions/4181018/what-is-the-pros-and-cons-of-using-out-parameter作为一个关于out参数的非常好的讨论,它涵盖了第一个提到的方法。 – 0lukasz0

回答

1

函数返回计算结果,正在通过了 参数返回的状态(不是所有的语言都支持输出参数,这似乎 错误的,因为一般你不要指望参数进行修改)。

如果语言支持多个输出值,那么语言显然是支持它们的。这是一个耻辱,不使用它们(除非有强烈的意见,在特定的社区对他们 - 这可能是语言的情况下,尝试和做一切)

函数返回对象/缺点是 你必须创建人工类只是为了返回函数结果或 使用对没有语义含义 - 你知道哪个参数是它的顺序 )。

我不知道那个缺点。在我看来,名为“MyMethodResult”的记录或类本身应该有足够的语义。你总是可以在例外情况下使用这样的课程,如果你当时只处于特殊状态。根据我的观点,创建某种阵列/联合/对将不太可以接受:您将不可避免地在某处丢失信息。

如果你的状态就是成功/失败就可以返回计算 值,并在错误的情况下抛出异常(看起来像最好的 的办法,但只有成功/失败的情况下工作和不应该 被滥用来控制正常的程序流程)。

不!这是最糟糕的做法。例外情况应该用于确切的情况。否则,他们将停止调试程序,将同事放在错误的脚上,损害性能,填写日志记录系统并调试单元测试。如果你创建了一个方法来测试一些东西,那么测试应该返回一个状态,而不是一个例外:对于执行,返回一个负值是而不是例外。当然,如果你在解析过程中用完了一个文件中的字节,肯定会引发异常,但是如果输入不正确,并且你的方法被称为checkFile,就不要抛出异常。

函数返回值,函数参数委托给 onSuccess/onFailure程序。

我只会使用那些如果你有多个结果共享。它比班级/记录方式更为复杂,而且更难维护。我使用这种方法返回多个结果,但我不知道结果是否被忽略,或者用户是否想要继续。在Java中你会使用一个监听器。这种操作可能更多地被功能语言所接受。

有具有状态字段(状态完整)方法的类,和 方法返回计算结果(我更喜欢具有 无状态/不可变的对象)。

是的,我更喜欢那些。有结果的生产者和结果本身。几乎没有必要将这两者结合起来并创建一个有状态的对象。

最后,你想要去producer.produceFrom(x):结果在我看来。如果我的计数正确,这可以是选项1或2a。是的,对于2a,这意味着写一些额外的代码。

+1

Mods,我试图以客观的方式回答这个问题,通过引入参数。漂亮,请不要在这里有战争般的维基百科,让适度的人为你做好工作。如果它的有用性和主题,它应该*留*。 –

+0

感谢您在本次讨论中的输入。我给+1,虽然有一些我不完全同意你的陈述。首先,我不认为out参数是非常好的选择。它们可能非常混乱,并且很容易忽略使用out参数的函数的可能副作用。我同意2a似乎是非常强大的选择,只要你的代码保持DRY,额外的代码在这里没有错。此外,您提出了一个很好的观点,提到回调场景中增加了复杂性。我们都同意,异常只应用于故障情况。 – 0lukasz0

+0

我并不特别喜欢输出参数。但是,如果编程语言被明确写入使用输出参数(并且它们用于例如标准库),那么我认为您不应该忽视它们作为程序员。程序员应该尝试并适应编程环境,否则代码将成为编程风格的大杂烩。 –

1

我的倾向是要么使用out参数,要么使用“open-field”结构,它只包含公共字段并指定其目的仅仅是携带这些字段的值。尽管有些人认为所有东西都应该被“封装”,但我会建议如果计算自然会产生两个称为Moe和Larry系数的值,则指定该函数应该返回“带有double类型字段的普通旧数据结构称为MoeCoefficientLarryCoefficient“将用于完全定义结构的行为。虽然结构必须在执行计算的方法之外被声明为数据类型,但将其内容作为公共字段公开会清楚地表明与这些值关联的语义都不包含在结构中 - 它们都是包含在返回它的方法中。

有些人会争辩说,结构应该是不可变的,或者它应该在其构造函数中包含验证逻辑等,我会建议相反。如果结构的目的是允许一个方法返回一组值,那么该方法的责任应该是确保它将适当的值放入结构中。此外,虽然将构造函数暴露为“便利成员”的结构没有什么问题,但是单独将代码分别返回结构体填充的代码可能比调用构造函数更快更清晰,特别是如果要存储的值在一个字段中取决于存储在另一个字段中的值。

如果一个结构只是暴露其领域公开,那么语义是很清楚的:MoeCoefficient包含已写入MoeCoefficient的最后一个值,并LarryCoefficient包含写入LarryCoefficient的最后一个值。这些值的含义完全取决于编写它们的任何代码。隐藏属性背后的领域掩盖了这种关系,并且也可能阻碍表现。