提问人:Java Jive 提问时间:2/26/2018 更新时间:3/26/2018 访问量:316
方法中的赋值调用不良做法?
Assignment in method call bad practice?
问:
这是我向 Stackoverflow 提出的第一个问题,尽管我已经是多年的消费者。如果我违反规则,请原谅我。这当然不是我的本意。我已经仔细审查了这些规则,并相信我在可接受的范围内。但是,如果存在使用错误,请您指出这些错误,以便我将来更加合规。
我教高中生编程。这学期我们正在学习 C#。上周我们研究了递归。我分配了几个可以用递归解决的经典问题,其中之一就是幂。
我的一个学生提交了以下代码作为使用递归的幂运算解决方案(他确实允许我在这里发布它)。方法调用中的任务给了我威利斯,但当我告诉他这是不好的做法时,他抗议说“它有效”,对他来说“有意义”,而且他“一直都在这样做”。
static void Recur(int n1, int n2, int n3)
{
if (n2 > 0)
{
Recur(n1, n2 - 1, n3 *= n1); // this is the line in question
}
else
{
Console.WriteLine("The number calculated recursively is: {0}", n3);
}
}
我很难想出一些具体的东西来告诉我的学生,为什么在方法调用中进行作业通常是不好的做法,除了 1) 意外副作用的可能性,以及 2) 维护的困难。
我在网上搜索了关于这个问题的每一个短语,但结果却是空手而归。我确实看到了一本名为“Clean Code”的书,作者是Robert C. Martin,但我不拥有。
我和学生的关系有点像父母的关系。他们有时不会对我所说的话投入太多精力,除非我能用独立消息来源证实。如果我能指出一个关于将作业放在方法调用中的明确声明,我的学生会更倾向于停止这种烦人的习惯。
这种用法会打扰其他人吗?我是否期望他改变他做事的方式?他今年15岁,但前途一片光明。他是那些“明白”的学生之一。我不希望他养成不良习惯。
感谢您的时间和意见。
答:
在发布的代码中有很多可以改进的地方:
保持一致
为什么不打电话?为什么会受到不同的对待?这可能会在审查/维护代码时造成混淆。
Recur(n1, n2 =- 1, n3 *= n1)
n3
不要做不必要或多余的工作
之后是否使用过?不?那为什么要浪费时间分配一个从未使用过的值呢?
n3
Recur(n1, n2 - 1, n3 *= n1)
不改变方法参数被认为是很好的做法(当然,除非它们通过引用传入)。为什么?因为它使调试和理解代码的工作方式变得更加困难;初始条件在方法执行时发生变化,使得跟踪可能的错误、优化、改进等变得更加困难。
总而言之,我避免使用这些模式,因为我的记忆力很差:
var i = 0;
Foo(i += 1);
Bar(i);
传递到什么?是还是是?我不记得了,我每次都要查。审查此代码的人可能会遇到同样的问题。这些聪明的技巧不会使代码工作得更快或更好,并且它避免了总共一行代码......不值得。Foo
0
1
错误的代码是这样的:您的学生没有看到任何问题,因为方法参数没有。只要定义它们,你就会看到这种和平的代码会导致编译错误。n3 *= n1
final
final
为什么要使用?因为这样可以确保方法参数不会在方法内用于任何其他目的。这使得代码更不容易出错,更可靠。将一个变量用于一个目的也会使代码更容易被其他人理解,这在行业中很重要。final
正如其他人已经指出的那样,为 n3 赋值是没有意义的,因为代码中没有使用变量 n3 的进一步。
他声称这“对他来说很有意义”,这表明他不在现实生活中,在行业中进行软件开发 - 从小公司开始,到谷歌或Facebook。其中一个要求是代码应该是可维护的。这种代码的和平不是。
关于“前途光明”:你怎么知道的?他赢得过任何编程比赛吗?他关于他“一直这样做”的论点是相当薄弱的。问他为什么要这样做?给他一个关于代码质量的小研究。也许这会帮助他稍微了解一下软件开发。
评论
n3
Recur(n1, n2 - 1, n3 * n1);
=