Android编程规范

994593785 8年前
   <h2><strong>命名规范</strong></h2>    <ol>     <li> <p><strong>基本原则</strong></p> <p>(1) 代码风格与android源码保持一致</p> <p>(2) 命名要清晰明了、有明确含义</p> <p>(3) 同一产品命名风格要保持一致,避免一意多词</p> <p>(4) 同一作用域,不能有变量重名,如局部变量与全局变量重名</p> </li>     <li> <p><strong>包名</strong></p> <p>(1) package命名如com.brian.xx.yy.zz,xx为产品,yy为模块,zz为子模块</p> <p>(2) 模块划分,按以下两种方式均可,但需要项目组统一</p>      <ul>       <li>按产品业务划分,如<br> com.brian.example.homepage 和 com.brian.example.player</li>       <li>按逻辑功能划分,如<br> com.brian.example.homepage.ui 和 com.brian.example.homepage.logic</li>      </ul> </li>     <li> <p><strong>类成员命名,参考android源码,如</strong> android.content.pm.PackageManager<br> (1) 类: public abstract class PackageManager<br> (2) 函数: public abstract PackageInfogetPackageInfo(String packageName)<br> (3) 常量: public static final int GET_ACTIVITIES= 0x00000001;<br> (4) 静态变量: static ComponentName sComponent;<br> (5) 成员变量: ComponentName mComponent;<br> (6) 临时变量: ComponentName component;</p> </li>     <li> <p><strong>对于简单的内部类,或则DTO(数据传输对象),成员变量名称可以不带前缀m</strong></p> <pre>  <code class="language-java">public final class Message implements Parcelable {  /**  * User-defined message code so that the recipient can identify   * what this message is about. Each {@link Handler} has its own name-space  * for message codes, so you do not need to worry about yours conflicting  * with other handlers.  */  public int what;    /**  * arg1 and arg2 are lower-cost alternatives to using  * {@link #setData(Bundle) setData()} if you only need to store a  * few integer values.  */  public int arg1;     /**  * arg1 and arg2 are lower-cost alternatives to using  * {@link #setData(Bundle) setData()} if you only need to store a  * few integer values.  */  public int arg2;  }</code></pre> </li>     <li> <p><strong>接口命名,参考android源码,如android.view.View.OnClickListener</strong></p> <pre>  <code class="language-java">/**  * Interface definition for a callback to be invoked when a view is clicked.  */  public interface OnClickListener {    /**     * Called when a view has been clicked.     *     * @param v The view that was clicked.     */    void onClick(View v);  }</code></pre> </li>     <li> <p><strong>资源命名</strong></p> <p>(1) 文件名(字母小写和下划线组成)</p>      <ul>       <li>activity_main.xml</li>       <li>ic_launcher.png</li>      </ul> <p>(2) 资源名id(字母小写和下划线组成)</p>      <ul>       <li>android:id="@+layout/loading_view"</li>       <li><string name="app_name">应用名称</string></li>      </ul> </li>    </ol>    <h2><strong>代码排版</strong></h2>    <ol>     <li> <p><strong>文字编码</strong></p> <p>(1) 统一使用utf8编码</p> </li>     <li> <p><strong>缩进对齐</strong></p> <p>(1) 代码缩进采用 <strong>4个空格</strong></p> <p>(2) 代码行首,合理缩进,以简洁明了为原则</p> </li>     <li> <p><strong>空格</strong></p> <p>(1) 条件语句,关键字与“(”用空格隔开,如 if (xx)、while (i> 3)</p> <p>(2) 注释内容,左右用空格隔开,如 // xxx,/ <em>xxx</em> /</p> <p>(3) 比较操作符、赋值操作符、算术操作符、逻辑操作符、位操作符,等双目操作符的前后加空格</p> <pre>  <code class="language-java">if ( (a >= b) && (c <= d) )  if (size >= MAX_SIZE)   a = b + c;  a *= 2;  a = b ^ 2;</code></pre> <p>(4) "!"、"~"、"++"、"--"、"&"(地址运算符)等单目操作符前后不加空格</p> <pre>  <code class="language-java">*p = 'a';  flag = !isEmpty;   p = &mem;   i++;</code></pre> <p>(5) 逗号、分号(非行结束符号)在后面加空格,前面不加空格</p> <pre>  <code class="language-java">int x = 1, y = 2, z = 3;  function(x, y, z);  for (inti = 0; i < 10; i++)</code></pre> </li>     <li> <p><strong>条件语句(if、for、while、do)</strong></p> <p>(1) 条件语句,使用完备的括号</p> <pre>  <code class="language-java">if (a == b && c == d) // BAD  if ((a == b) && (c == d))// GOOD</code></pre> <p>(2) 条件语句,独自占一行,执行语句不得紧跟其他</p> <pre>  <code class="language-java">// BAD  if (flag) doSomething();    // GOOD  if (flag){    doSomething();  }</code></pre> <p>(3) 条件语句,不论语执行句有多少行都要加“{}”</p> <pre>  <code class="language-java">// BAD  for (inti = 0; i < 10; i++)    doSomething();    // GOOD  for (inti = 0; i < 10; i++){    doSomething();  }</code></pre> </li>     <li> <p><strong>代码结构</strong></p> <p>(1) 一行只写一条语句</p> <pre>  <code class="language-java">// BAD  x = a + b; y = c + d; z = e + f;    // GOOD  x = a + b;  y = c + d;  z = e + f;</code></pre> <p>(2) 代码以“段”来编写,作用相近的代码写在一段,段与段间以空行分开,注释也相应以“段”来注释,如</p> <pre>  <code class="language-java">public void filterData(Data in, Data out) {      // 预处理    clip(in.a + 100);    clip(in.b + 200);    clip(in.c + 300);      // 滤波    intavg  = (in.a + in.b + in.c) / 3;    int tmp1 = in.a + avg;    int tmp2 = in.b - avg;    int tmp3 = in.c + tmp1 + tmp2;      // 保存结果    out.a = tmp1;    out.b = tmp2;    out.c = tmp3;  }</code></pre> <p>(3) 代码文件中从上到下,函数依次按照调度、被调度的顺序出现,例如</p> <pre>  <code class="language-java">public void funA() {    funB();    ...  }    public void funB() {    ...  }</code></pre> </li>    </ol>    <h2><strong>代码注释</strong></h2>    <ol>     <li> <p><strong>基本原则</strong></p> <p>(1) 注释语言必须准确、简洁、易懂,能直接反映编程思路</p> <p>(2) 统一使用中文作为注释语言,除非直接拷贝第三方的英语注释</p> <p>(3) 注释比例没有严格的要求,建议不低于15%</p> <p>(4) 注释要与代码保持一致,代码作用变了,注释也要更新</p> <p>(5) 对于逻辑复杂、使用有限制的代码,需要重点注释</p> </li>     <li> <p><strong>必须注释</strong></p> <p>(1) 文件</p> <p>(2) 类</p> <p>(3) 函数(对外接口public函数)</p> <p>(4) 常量</p> <p>(5) 成员变量(有特殊含义)</p> <p>(6) 静态变量</p> <p>(7) 特殊逻辑、定制逻辑、有坑逻辑、临时逻辑</p> </li>     <li> <p><strong>建议注释</strong></p> <p>(1) 复杂的逻辑</p> <p>(2) 重要的分支,如 if-else,switch-case</p> <p>(3) 重要的循环,说明,“每次循环遍历…”</p> </li>     <li> <p><strong>注释样式</strong></p> <p>(1) 注释样式参考android源码</p> <p>(2) 代码以“段”来编写,注释也相应以“段”来注释</p> <pre>  <code class="language-java">/**  * 函数注释  */  public void foo() {  }    /**  * 函数注释  * @param a  * @param b  * @return  */  public int math(int a, int b) {  }    /**  * 成员变量注释  */  public int mValue;    // 一段代码注释  xxx  xxx  xxx    xxx  xxx // 一行代码注释  xxx    // if分支注释(1)  if (true) {  }  // else分支注释(1)  else {  }    if (true) { // if分支注释(2)  }  else { // else分支注释(2)  }    // switch注释  switch (xxx) {    // case注释(1)    case xxx : break;    case xxx : // case注释(2)      break;    default: break;  }</code></pre> </li>    </ol>    <h2><strong>模块设计</strong></h2>    <ol>     <li> <p><strong>基本原则</strong></p> <p>(1) 开放封闭</p> <p>(2) 单一职责</p> <p>(3) 倒置依赖</p> <p>(4) 高内聚低耦合</p> </li>     <li> <p><strong>分层设计</strong></p> <p>原则上,程序实现业务功能时,按MVC模式,从上至下进行分层设计</p> <p>(1) 应用层:负责UI展示、下发操作指令</p> <p>(2) 服务层:负责控制逻辑、数据维护</p> <p>(3) 数据层:负责底层数据获取,包括网络、数据库、文件、底层算法</p> </li>     <li> <p><strong>模块交互</strong></p> <p>(1) 原则上,下层功能代码不能import上层业务的package,如下层操作数据库的类不能import上层UI的activity</p> <p>(2) 上层模块调度下层模块,通过下层public接口函数</p> <p>(3) 下层模块回调上层模块,通过interface执行回调(不用handler)</p> <p>(4) 广播或则单播监听事件,同时具有attach和detach操作</p> <p>(5) 非特殊情况,调度与回调默认在UI线程执行</p> <p>(6) 非特殊情况,获取对象的变量统一使用getter、setter操作</p> </li>     <li> <p><strong>代码分离</strong></p> <p>(1) 分开:界面代码、数据代码</p> <p>(2) 分开:业务相关代码、底层通用模块代码</p> <p>(3) 分开:基本模块、特殊定制模块</p> </li>    </ol>    <h2><strong>函数设计</strong></h2>    <ol>     <li> <p><strong>基本原则</strong></p> <p>(1) 一个函数只做一件事</p> <p>(2) 按抽象层划分函数</p> <p>(3) 向下调度原则</p> <p>(4) 高扇入低扇出</p> </li>     <li> <p><strong>其他建议</strong></p> <p>(1) 代码以“段”编写,合理分隔不相关的代码段</p> <p>(2) 禁止代码中实现与函数名不相关的逻辑</p> <p>(3) 禁止代码中出现魔鬼数字</p> <p>(4) 避免多处出现雷同的代码,应提取公共的功能函数,或则调整调度入口</p> <p>(5) 避免嵌套逻辑太深,超过3~5层,建议优化</p> <p>(6) 避免复杂的复合判断条件,建议分拆</p> <p>(7) 避免山寨临时逻辑</p> <p>(8) 函数的参数超过5个,则使用参数对象封装参数,有助于扩展接口</p> <p>(9) 降低临时变量的生命周期</p> <p>(10)废弃的代码及时清理</p> </li>    </ol>    <h2><strong>其他参考</strong></h2>    <ol>     <li> <p>《Android Code Style》</p> <a href="/misc/goto?guid=4959722584936538654" rel="nofollow,noindex">https://source.android.com/source/code-style.html</a></li>     <li> <p>《Java Programming Style Guidelines》</p> <a href="/misc/goto?guid=4958871044409555523" rel="nofollow,noindex">http://geosoft.no/development/javastyle.html</a></li>     <li> <p>《Google Java Style》</p> <a href="/misc/goto?guid=4959722585068965282" rel="nofollow,noindex">https://google.github.io/styleguide/javaguide.html</a></li>    </ol>    <p> </p>    <p>来自:http://www.jianshu.com/p/e4229061fceb</p>    <p> </p>