如何提高Android应用程序的代码质量
提高程序的代码质量,是我一直以来想追求的,但是在实际操作过程中时常感到比较困难。主要在于提高代码质量对基本功的要求比较高,同时要有好的抽象能力与预见性。所以想在较短时间里提高能力基本不可能,第一需要学习基础知识,第二就是要多看高手写的代码,第三就是学以致用,多模仿与练习,逐渐形成自己的想法。
提高代码质量,大的方针就是:
结构清晰;避免重复;简单直观;方便扩展
结合工作中的实践,我总结了容易被掌握的几点:
程序组织方面
1.Package分类命名要一目了然
一个比较大的顶目,最好按照模块、功能分类来组织Package。
因为开发时常常某几个人负责一个模块或功能,查看代码时也常常只查看某个模块的代码,按照模块功能分类是很自然的事。
Package命名最好就是模块或功能名称,比如订单模块,举个简单例子,Package名为com.companyname.producename.order。
2.类的命名要一目了然
常用一些组件、模块在名字上就要体现出其性质,比如所有的Activity的命名,都命名成xxxActivity.java的形式,所有的Adapter都命名成xxxAdapter.java的形式,维护时一看就知道该类是什么作用;而且名字也要反映出该类所代表的模块功能与用途,比如订单管理主界面,就叫OrderManagerMainActivtiy.java,一目了然,不用进去看就知道该类的用途,很省事。
3.提炼Library工程
多个项目共用的一些功能,应该都归到Library工程中,使用时再引用Library即可。比如网络访问、图片处理、数据库的封装等都可以写到Library工程中。
同时如果项目特别庞大,可以将项目进行分层,比如可以将项目分为业务、数据收发与界面展示三层,业务与数据收发可以作为Library工程,界面展示作为主工程再引入其它两个Library工程。
这样处理的好处很多,维护方便、结构清晰、减少重复、方便扩展等。
Java程序方面
1.引用优秀开源框架
不重复造轮子,拿来主义,在软件开发中能大大提高开发效率与开发质量。优秀的开源框架在性能与代码质量上都是一流的,为我所用,当然能提高自己项目的效率,不过第三方的框架是来辅助项目的,不能喧宾夺主,大量的开发工作还是需要自己来完成。一些比较好的框架,比如:log4j、gson、android-async-http等。
2.封装基础功能
有些功能是我们项目的基石,许多模块都可能会用到,比如文件操作、日期时间操作、图片操作、字符串操作、JSON操作、http操作等等,我们不应该在用到时,就在哪个类里随手写个函数,而是在开发开始时就将这些基础功能封装成工具类,部分工具类中的函数可以都写成静态函数,方便随时使用。比如可以封装一个类名为DateUtil.java,程序中许多与日期时间相关的操作,直接调用该类就可以了。
这样做的好处非常明显:维护方便、使用方便、减少重复。
3.限定类与函数的大小
类与函数太大,坏处很明显,维护难,理解难,所以在开发时,就要限定类与函数都不能过大,如果类的功能太复杂时,代码本来就很多,就要考虑将该类分解了多个类;如果函数过大,就要将该函数分解为多个函数或是提炼成类来处理。
养成好的习惯非常重要,如果平时不注意,未来维护起来会降低效率。
4.函数变量命名一目了然
这个虽是小事,但是起个好名字,会提升维护效率,如果函数或变量名字起得不好,坏处很大,会给维护带来很多困惑。名字一般采用驼峰法,如果是常量则需要大写,用下划线“_”分隔。变量的名字也不必要带类型的识别,突出功能即可,全局变量也不必搞个“g”或者“m”作为前缀,因为IDE都会帮我们识别,我们尽量做到突出重点即可。
5.活用java泛型
泛型特别好用,许多重复性的代码,利用泛型,就可以进行合并,大大方便了开发,减少了程序重复代码。举个例子,比如网络请求,服务器返回给我们一系列的对象,这些对象有共用的也有特别的,那我们接收返回的数据,转换成对象时,是不是要写很多个类进行转换,其实利用泛型,完全可以写一个类,专门用来进行转换。比如:
public class ResponseObj<T> { public int result; public String content; public T special; }
6.采用接口或抽象类编程法
采用接口编程无疑是提高代码质量的一大法宝,好处非常多,但是灵活运用起来比较难。一般情况下我们可以将某个功能固定的流程提炼成成几个函数,放入接口或抽象类中。然后在具体的子类实现这些函数,使用时用接口或抽象类来保持子类的引用。
比如http通信,有两种方式:HttpClient与HttpURLConnection,我们如果想随意切换这两种方式进行http通信,有个好办法,就是提炼一个抽象类,将http的主要几个功能写在函数中,最后实现时,分别继承该抽象类,并采用各自方法去实现相关抽象方法。举个简单例子:
public abstract class HttpUtil { protected int responseCode; public int getLastResponseCode(){ return responseCode; } abstract public void get(String url); abstract public void post(String url); }
public class HttpClientUtil extends HttpUtil { public void get(String url) { HttpGet httpget = new HttpGet(url); ...... } public void post(String url) { HttpPost httppost = new HttpPost(getUri(url)); ...... } }
public class HttpURLUtil extends HttpUtil { public void get(String url) { execute(url,"GET"); } public void post(String url) { execute(url,"POST"); } private void execute(String url, String method) { ...... } }
使用起来很简单,想进行替换也非常方便,new不同的子类即可,其它代码不用改。
public class Test { public static void main(String[] args) { //HttpUtil httpUtil = new HttpClientUtil(); HttpUtil httpUtil = new HttpURLUtil(); httpUtil.post("www.test.com"); } }
另外可以在系统的提供的组件基本上进行再次封装,加入共性的业务与处理。比如我们可以对系统提供的Activity再次封装,如取名AbstractBaseActivity.java,作为其它Activity的父类,里面优化流程,加入基础业务逻辑,这样也可以减少重复,未来扩展也非常省事。
Android框架方面
1.使用xml替代图片与代码
虽然xml文件在被系统利用前需要进行解析,比纯代码方式效率要低,但是它更直观简单,在开发与维护方面对效率的提升是巨大的,所以能用xml实现的布局或者属性就该用xml,另外有些图形界面完全能用shape实现,就没必要用图片,因为图片非常占资源;动画也可以在xml里配置。另外像dimen、style、color等等尽量利用。
2.自定义控件
在应用中有部分组合UI布局用得比较普遍,比如搜索框、带图片与背景变换的按钮等,实现起来也有多种选择,比如在xml中用include引入布局的方式,但是如果能做成自定义控件,使用与扩展起来更方便。
3.熟练使用Fragment
Fragment很好的对Activity进行了模块化,而且拥有自己的生命周期,在Activity中加入Fragment能处理复杂的界面,方便我们进行扩展。