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>