方法调用不好的做法中的作业?
这是我对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)维护的困难之外。
我在网上搜索了关于这个问题的每一句话,但都是空手而回。 我确实看到了Robert C. Martin所着的一本名为“Clean Code”的书,我没有这本书。
我和学生的关系有点像父母。 除非我可以用独立的资料来证实,否则他们有时不会在我说的话中投入很多股票。 如果我可以指出一个明确的声明,即将任务放在方法调用中,我的学生会更倾向于停止这种恼人的习惯。
这个用法是否会打扰其他人? 我是否期望太多想要改变他一直在做的事情? 他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。
他对“对他有意义”的说法表明,他并不关心现实生活中的行业软件开发 - 从小公司开始,到Google或Facebook。 其中一个要求是代码应该可以维护。 代码的和平不是。
关于“在他前面有一个充满希望的未来”:你怎么知道的? 他赢得了任何编程比赛吗? 他认为他“一直这样做”的论点相当薄弱。 问他为什么要这样做? 给他一个关于代码质量的小研究。 可能这会帮助他了解一点点软件开发。
链接地址: http://www.djcxy.com/p/41363.html