我正在开发一个用java编码的复杂企业应用程序,它由复杂的对象组合驱动。例如:在特定情况下,要执行操作,这就是流程:
login() ->
Followed by defined sequence of 10 to 20 method calls in different classes ->
Followed by a logout()
在框架内,几乎所有操作(包括登录,注销和许多10到20个方法调用)都没有返回类型。任何错误的行为都由框架处理。说,在登录
public void login(){
try{
//login actions
//chained sequence of calls
}catch(){
// framework handling exceptions and other rollback options
}
}
中间10到20个动作是对框架的不同层次结构的不同对象的方法调用。
随机类看起来像这样:
class someobject{
def variable
void action1(){ do something on variable }
void action2(){ do something on variable }
...
}
变量经常改变状态,这些动作只有一个我觉得很烦人的框架定义的序列。
我会说,或许如果有适当的返回类型或至少有一些这样的方法,就像在login()
的情况下说布尔值一样,生活会容易得多。由于对一系列空隙返回功能的严格遵守,我发现很难通过调试来理解流程,单元测试对我来说也是一场噩梦。
现在,我的印象是,编写返回某些内容的函数总是更好,尤其是在涉及一系列操作时。那么,这是一个安全的推定吗?我想对此发表意见。如果我错了,请纠正我。
答案 0 :(得分:4)
方法的最基础可测试性是通过其返回码。在login
的情况下,您需要(如您所述)能够测试您是否已登录,并且boolean
返回是显而易见的方式。否则你必须检查一些属性,这似乎是不必要的非原子和复杂的(虽然可能因其他原因需要)。
对我来说,这个论点延伸到任何有意义的方法。使用void
返回码非常常见,但更多是由于旧习惯而不是出于好的设计原因。简单的属性设置器虽然是反例,但我确信还有其他的。
答案 1 :(得分:2)
当一个方法对类中的本地数据进行操作时,void方法是完全合理的,只要它模拟一些在类的上下文中有意义的“行为”。例如,如果你有一个对其内容进行排序的SpecialSortedList,即myList.sort(),那么sort()方法将是无效的,因为它模拟了与SpecialSortedList相关的一些行为。
如果一个方法不对一个类中的本地数据进行操作,即它通过参数接受其数据并返回一些数据(即不依赖于本地数据),那么将它声明为静态甚至移动是一种好习惯。它是一个实用工具或帮助者类。
答案 2 :(得分:2)
在我看来,没有必要总是在行动链上返回一些内容完全取决于你的要求。即,在登录身份验证方法中,最好返回布尔结果以简化。如果一系列行为是独立的,那么在我看来,没有必要返回任何不会被任何行动使用的东西。因此,如果一个动作的结果影响下一个动作,那么它应该返回一些简化和测试的东西,这样你就可以直接从导致问题的方法的输出中获取。确定方法后,您可以检查已识别的特定方法。所以基本上每件事都取决于你的要求。如果你的要求在没有归还的情况下得到更好的处理,那么你就应该去做。此外,你应该遵循最佳实践或设计模式的有效性,这将更好地适用于所有情况,你可以摆脱最后造成混乱。这只是我的意见。
答案 3 :(得分:0)
越来越多,我更喜欢返回类似状态代码而不是void的东西。这做了几件事:
我的偏好是,尽可能让大多数函数占用参数,返回答案而不更改任何类变量。正如Jaco所提到的,这些可以被声明为静态,甚至可以转移到实用程序类。然后你可以使用一些控制器函数来使用返回值的函数。
答案 4 :(得分:0)
我会将答案分为两部分:
何时返回“void”有用 -
如果方法仅返回一个值以指示不正确的状态/异常,那么它应该返回“void”。 Exception应该处理所有错误场景,而不是说“布尔”返回值。现在,调用代码需要再次验证布尔值和异常。如果它只抛出Exception,那么它就更容易了。更清楚的是调用代码。
什么时候返回void不太有用 -
如果方法执行任何操作并返回值作为结果,则不应返回“void”,需要返回相关的结果类型(布尔/整数/对象等)。
通常,返回值应该与方法是否返回实际对应。它不应该对应于方法是否正确执行(好吧,它应该是)。所有输入验证/异常情况都应该通过抛出相应的异常来处理。例如,当输入无效时抛出IllegalArgumentException,而不是返回“boolean”表示方法没有执行。