规范Android开发Android开发经验谈

Clean Code Notes(代码规范)

2017-08-19  本文已影响46人  Vaycent
/* edit by Vaycent on 2016/03/22
Pls feel free to contact, vaycentsun@gmail.com
*/

[TOC]

Clean Code Notes


1_命名

1.1_命名要点

1.1.1_类名与对象名

使用名词名词短语,如Customer、WikiPage、Account、AddressParser
类名使用每单词首字母大写,如AccountGroup、FoodRecords

1.1.2_方法名

使用动词动词短语,如postPayment、deletePage、使用前缀get、set、is等
变量名/方法名使用首单词小写,其余单词首字母大写,如getMedicationAlarm、bpMeasurementValue

重载/重构(overload):同一个类中,同名方法,但参数不同,Java会将其视为唯一方法
重写(override):子类继承父类后,在参数与返回值相同的前提下,重新定义方法体

重载时(overload),使用描述了该参数静态方法,比直接New该参数的方法要好,例如:
Complex fulcrumPoint = Complex.fromRealNumber(23.0);
通常好于
Complex fulcrumPoint = New Complex(23.0);


2_函数(方法)

2.1_函数要点

短小:函数尽可能短小、简洁、结构清晰
少参数:尽可能减少输入的参数。尽可能不使用boolean值作为输入,若有则进行拆解,如:

Boolean isSuite;
//...
render(isSuite);
//拆分成  ====>>
//...
renderForSuite();
renderForSingleTest();

只处理一个抽象层级:避免让读者混淆,无法判断内容是基础概念还是细节,如不在函数里同时处理版面和内容
只做一件事:在保证同一个抽象层级的前提下,函数只负责做一个步骤(一件事)
异常代替错误码:错误码通常用一个类(class)或者枚举(enum)来定义,其他许多类都得导入或者使用它。但当以后修改的时候,就需要重新构建或部署。使用异常来代替错误码,新异常可以继承基类,派生出来,无需重新部署。


3_注释

3.1_注释要点

3.1.1_辅助信息

为函数、变量、类等给予辅助解释,提供基本信息。这类注释若能通过函数、变量名字的方式传达信息的话,能避免就避免使用。例如:

//Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();

这个注释就不如使用responderBeingTested()作为函数名

3.1.2_传达作者的意图

在函数名、变量名能提供足够要传达信息的前提下,注释用来描述作者此段代码的意图为更佳,而不是仅仅用于解释变量、函数代表的意义。例如在一段算法的注释当中,解释作者的思路,而不是解释变量名代表的意义。

3.1.3_TODO注释

TODO是一种程序员认为应该做,但由于某些原因目前还没做的工作。它可能是提醒删除某个不必要的特性、或要求他人注意某个问题、或恳请别人取个好名字、或提示对依赖于某个计划事件的修改,等等...大多数IDE都提供了特别的手段来定位TODO,以Android Studio为例:

[图片上传中。。。(1)]

3.1.4_Javadoc注释

注释可用于编写描述Project的Document介绍,以/** */包括为内容,以p为段落,以br为换行,以@param为输入参数,以@return为输出参数。以下Android Studio代码为例:

  1. 在Tools中选择Generate JavaDoc
  2. 修改Other command line argument(自己sdk下android.jar路径),-bootclasspath "/Users/smartone_sn2/Documents/android_SDK6.0_for_Studio/android-sdk-macosx/platforms/android-23/android.jar"
  3. 中文解释需用encode,与android.jar之间用空格隔开,-encoding utf-8 -charset utf-8
/** * 从url链接中获取特定parameter参数值.<p> * ... (方法的详细说明第一行)<br> * ... (方法的详细说明第二行)<br> * ... (方法的详细说明第三行) * @param url 作用于的url * @param parameter 要获取的参数名 * @return 特定参数的值 */protected static String getUrlParam(String url, String parameter) {String returnParameter = "";   if (url.contains("?")) {String paramUrl = url.substring(url.indexOf("?") + 1);      String[] paramStrs = paramUrl.split("&");      for (int i = 0; i < paramStrs.length; i++) {if (paramStrs[i].contains(parameter)) {returnParameter = paramStrs[i].substring(paramStrs[i].indexOf("=") + 1);            i = paramStrs.length - 1;         }}}return returnParameter;}

[图片上传中。。。(2)]

3.1.5_法律信息

公司代码规范要求编写与法律有关的注释,如版权、著作权声明。注意这类注释不是合同和法典,只要有可能,就指向一份外部的标准许可或其他文档。例如:

//Copyright (c) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
//Released under the terms of the GUN General Public License version 2 or later.  

3.1.6_警示

用于警告其他程序猿运行后会出现某种后果,或用来表示测试用例。例如下面注释解释了为何要关闭某个特定的测试用例:

//Don't run unless you have some time to kill
public void testWithReallyBigFile(){
    writeLinesToFile(10000000);
    response.setBody(testFile);
    ...
}

4_格式

4.1_垂直格式

4.2_水平格式

但IDE的自动Format功能一般会消除这些格式


5_面向过程与面向对象

引言
Java为面向对象的语言,但同样能使用“数据结构+过程”的面向过程式地编程。首先,“面向对象”并不一定比“面向过程”更加优越,两种方式在不同情景中各有优劣。面向过程更善于添加新函数,分析思想是拿到问题后,拆分成逐个步骤解决,善于分析一个不完整的事物问题。面向对象更善于添加新类,分析思想是经过整体分析自顶而下,定于每个对象再组装起来,善于分析一个完整的事物问题。

5.1_抽象

抽象:指把现实世界中某一样事物,提取出描述点,用代码形式表示。抽象一般不打算了解该事物的全部描述点,只关注与目标有关的方面。抽象出来的叫做类或接口(Java中),抽象按方式划分可分为:

5.1.1_数据抽象(数据结构)

用代码形式抽象出参数(事物特征),如抽象出正方形有锚点x坐标、锚点y坐标、边长等特征

public class Square{
    public Point topLeft;
    public double side;
}

public class Rectangle{
    public Point topLeft;
    public double height;
    public double width;
}

public class Circle{
    public Point center;
    public double radius;
}

public class Geometry{
    public final double PI = 3.14;
    
    public double area(Object shape) throws NoSuchShapeException{
        if(shape instanceof Squre){
            Square s = (Square)shape;
            return s.side * s.side;
        }else if(shape instanceof Rectangle){
            Retangle s = (Retangle)shape;
            return s.height * r.width;
        }else if(shape instanceof Circle){
            Circle s = (Circle)shape;
            return PI * s.radius * s.radius;
        }
        throw new NoSuchShapeException();
    }
}

//要用时,需要取出Square、Rectangle、Circle的公有参数,定义方法体来使用

5.1.2_行为抽象(对象)

用代码形式抽象出函数(事物方法),如抽象出正方形有获取锚点坐标、周长、面积等方法

public class Square implements Shape{
    private Point topleft;
    private double side;
    
    public double area(){
        return side * side;
    }
}

public class Retangle implements Shape{
    private Point topLeft;
    private double height;
    private double width;
    
    public double area(){
        return height * width;
    }
}

public class Circle implements Shape{
    private Point center;
    peivate double radius;
    public final double PI = 3.14;
    
    public double area(){
        return PI * radius * radius;
    }
}

//要用时,直接使用Square.area()、Retangle.area()、Circle.area()

5.2_数据结构与对象的优劣对比

从以上对正方形、长方形、圆形面积的2种代码可看出,它们定义的本质是截然对立的,说明对象数据结构是对同一事物,使用了完全不同的分析方法

  1. 若此时需要添加一个功能,计算图形的面积是否大于100,若大于就返回100,则:
    数据结构:在Geometry中直接加入判断即可
    对象:需要分别在各个类中分别加入判断,控制输出的值,甚至有时需要改动更上一层父类的内容。

  2. 若此时需要添加三角形周长(新类)的计算,则:
    数据结构:不仅需要添加三角形的数据结构,Geometry类的area也不能用了,甚至调用Geometry的地方也要修改。
    对象:直接添加三角形的类,调用周长函数即可。

所以可得

5.3_面向过程与面向对象的对比结论

结论:

上一篇 下一篇

猜你喜欢

热点阅读