软件工程(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,你就什么都没学!

posted @ 2018-04-06 15:35  sequix  阅读(172)  评论(1编辑  收藏  举报