软件工程(2018)结对编程第一次作业
对题目本身的思考
本组遵循阿里巴巴Java编码规范进行开发,该规范对每一编码细节有详细的规定,和如此规定之原因。
那么阿里的编码规范用表格罗列了所有的检查项吗?没有它详尽的解释了每一项的原因、好处、缺点等等。
那么为每一项列出表格,我能得到对HTML表格的训练?或是某些表格生成工具的训练?
那么我的同伴能从表格中学到什么,他能知道哪里错了,但为什么?他不知。
所以这里我不会提供表格而是把我认为的问题一一列举,包括这样不好的原因和如何改正,为何这样改正好的原因。
正文
没有什么比一份糟糕的代码,能更帮助人学习编码风格的了。
苏阔的完整代码实现了大整数的加法,遗憾的是其并不是通过面向过程的方式写成的,所以关于面向对象编码风格的部分我们就说不到了。
代码一次性贴出很长,我们一部分一部分的分析。
package threethhomework;
1. 包命名习惯:所在公司、机构的域名反写,后接项目名,再接子包名。其中每一个点分割的部分应为一个单数的英语单词。显然上述代码中的包名是一个反例,正例如下:
package edu.sau.se.homework3;
public class rellaywork {
2. 类命名统一采用UpperCamelCase,即首字母大写的驼峰形式,原代码是一个反例,正例如下:
public class RealWork {
private static Scanner sc;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
//输入加数
System.out.println("请输入加数:");
String a = sc.next();
//输入被加数
System.out.println("请输入被加数:");
String b = sc.next();
//计算
int length = a.length()>b.length()?a.length():b.length();
int[] res = new int[length];
res = Calplus(a, b);
//打印结果
dis(res);
sc.close();
}
3. 这部分我们能看到程序员最不能容忍的错误——缩进不一致
4. 程序中加了注释,但以上注释是在侮辱读这份代码的人的智商,难道我不理解你的代码吗?难道你是在写教课书吗?用行话来说这种注释就是——repeating your code in comment!
5. 局部变量的命名在K&R时代是很推崇所谓最精简但清晰表达程序员意图的命名,但这种命名是建立在类似编程背景的程序员之间,比如两个Unix程序员都知道creat就是create。但在这个水平参差不齐而又需要多人合作的年代,清晰地表达意图才是王道,所以不要缩写单词。我们知道原代码要进行大整数运算,所以a和b的命名姑且可以,但sc、res、dis我就不能忍了,写成scanner、result、display能死吗。后续的代码中的局部变量还会出现糟糕的命名如first_1,但这篇博文是写给大家看的,所以同样的问题不会出现两次。
6. 第14行使用了三目操作符,但问题有三。
一,未使用空格分割;
二、重复计算;
三、没有使用括号圈出测试部分。
修改后如下:
int lengthA = a.length();
int lengthB = b.length();
int length = (lengthA > lengthB) ? lengthA : lengthB;
这样写虽然代码变长了,但好处有,
一、清晰,想想若代码若是以下这样的,上面这样写就很有必要;
server1.getRemoteAliveNumber() > service2.getLocalDeadNubmer() ? server1.getRemoteAliveNumber() : service2.getLocalDeadNubmer()
二、没有重复计算,并且当再次需要的a或b的长度时,也只需直接使用lengthA;
三、对他人友好,这是团队开发中代码风格设计哲学的核心。
7. 方法命名使用lowerCamelCase,即首字母小写的驼峰风格,原代码14行Calplus是个反例,缩写了calculate,又在后面加上了另一个动词plus,这是真的很令我抓狂,正例如下:
public int[] plus(int[] a, int[] b) {
后续所有的命名均以此为风格,不再吐槽。
//输入(方法)
private static String input()
{
String s = new String();
s = sc.next();
return s;
}
8. 这个方法从来没有被用过,您听说个奥卡姆剃刀吗,没用的东西删掉能死啊!?
//计算(方法)
private static int[] Calplus(String a, String b)
{
char[] first_1 = a.toCharArray();
char[] second_1 = b.toCharArray();
char[] first = new char[first_1.length];
char[] second = new char[second_1.length];
int[] res = new int [(first_1.length>second.length?first_1.length:second_1.length)+1];
first = InvertedArrary(first_1);
second = InvertedArrary(second_1);
res = Plus(first, second); //两个数组相加
//int res = CharToInt(first[0])+CharToInt(second[0]);
//System.out.println(res);
return res; //返回int型数组
}
9. Java提供基本类型byte,那么就不要按照C的习惯使用char。更一般地,在了解好一个工具的全部基础时不要开始写真正的代码(会被别人看的代码)。
10. 既然你用了a、b表示操作数,那么就一致性的使用这样的命名,后期改成first、second是什么鬼,这会让增加读代码的人理解时间。
if(j >= first.length) //当短的数组全部读完,长的数组没读完,则短取0参与计算
{
r = res_2[i] + 0;
}
else r = res_2[i]+res_1[j];
11. 花括号如果在一个分支、一层循环中有,那么所有分支、所有层中都要有。
// 打印结果数组
private static void display(int[] res) {
for (int i = 0; i < res.length; i++) {
if (res[i] == 0 && res.length > 2) {
continue;
} else {
System.out.print(res[i]);
}
}
}
12. 循环的测试条件中,不要调用函数,在没有编译器优化的情况下,其会严重影响效率,原代码没有这个问题,因为length是一个属性。给出一个反例:
for (int i = 0; i < str.length(); ++i)
13. 最后的问题,文件采用GBK编码,CRLF换行,不易代码交流。
改正
我很想把代码自己改了,但这样,su,你就什么都没学!