1.项目基类
毫不夸张的说,项目基类封装的质量决定你的开发速度,后期维护难易度。不过估计很多萌新并没有理解其中原因,那么我今天就来分析下,项目基类封装的质量有多重要。
首先通常来讲,入了门的安卓萌新们应该都知道,项目中的activity和fragment必须要有统一的基类,也就是我们常说的BaseActivity和BaseFragment(连这个都没有概念的同学,恭喜你,连萌新都不算╮(╯▽╰)╭),那么为什么我们需要这两个基类?
简单来说BaseActivity和BaseFragment有利于我们对整个项目中所有activity和fragment的统一管理,举个例子,界面跳转,应该没人不会写吧?通常我们会这么写(看过我另一篇文章的同学都知道,我是主用mvp模式进行开发的,不过这里的讲解,我尽量以mvc为例):
传送门:我的mvp框架
为了减少叙述,下面同一以BaseActivity为例
Intent intent = new Intent(this,LoginActivity.class);
startActivity(intent);
有的同学可能就不懂了,这个和基类有什么关系?我相信做过几个项目的同学应该都挺烦这个代码的,为什么呢,因为这两行代码毫无营养,但是你每次跳转界面却又不得不写,因为标准写法就是这样啊,有一定封装经验的同学可能会想,这还不简单,封装个utils类呗,比如下面这样:
ActivityUtils.goActivity(this,LoginActivity.class);
//======================================================
public static <S extends Activity> void goActivity(Activity activity, Class<S> cls ){
Intent intent = new Intent(activity,cls);
activity.startActivity(intent);
}
这样写相比每次都要自己去new Intent来说,确实好很多,但是在我看来还是不够简洁,如果我们在基类中添加一个方法,然后就可以简单只传入我们所必须的参数也就是我们所需要跳转的类名,如下:
goActivity(LoginActivity.class);
//======================================================
public <S extends Activity> void goActivity( Class<S> cls ){
Intent intent = new Intent(this,cls);
startActivity(intent);
}
这样,你会发现,我们传的参数真正做到了,只传我们觉得需要传的,不再需要重复的传入this了,也许你会觉得仅仅一个this而已,但是首先,跳转界面这个代码在项目里少说也会出现几十次,多传一个this,也就意味着你要多写几十次,其次,这里只是以跳转为例而已,还有更多复杂的场景。
如果说上面这个简单的例子还不能让你直观的明白基类的意义,那么我们再来一个例子,这次就不贴代码了,我们以实际场景中的业务为例,话说你写好了一个项目,现在突然需要在每个activity的onCreate初始化时额外加载一个第三方sdk的初始化方法,这个需求是很常见的,如果没有基类也就意味着,你需要每个activiy都去复制粘贴,然而有了统一基类时,你只需要去BaseActivity中的onCreate中加上这行代码即可,这也就是开始说的,方便对activity进行统一管理了。明白这点之后,为什么基类会影响开发速度和后期维护难易度,相信你就应该能想到了。
说了基类的重要性,再来简单说说该如何封装,当然,这里只介绍一些技巧,并不会为大家提供具体基类(如果确实需要例子的,请参考本人的mvp库),因为大家的项目千变万化,而且开发习惯各异,想要都使用一个统一封装基类是不太现实的,这也是为什么几乎没有人开源关于BaseActivity的封装框架,我们先来看一张图:
毫无疑问,BaseActivity就是我们项目的顶层封装基类,RefreshActivity和ListActivity从名字上就可以知道了,是基于顶层基类对特定功能的二次封装,而RefreshWebActivity则是基于RefreshActivity的二次封装,真正的界面是下面那几个。
明显的,DetailActivity是一个带有刷新web功能的界面,MainActivity则是可以刷新的主页面,GoodsListActivity是一个带有列表的商品清单界面,LoginActivity是一个普通的界面,功能单一,直接继承自BaseActivity。这么设计的好处在哪里呢?像带有列表的界面,对于一般的项目而言,通常少则出现几次,多则十几次几十次,这时如果我们直接继承自BaseActivity就会造成,列表的逻辑重复写很多次。
有人可能会提问,那直接把列表逻辑写在BaseActivity不就好了,何必再弄一个ListActivity?明确的说,这么设计并不好,如果遇到一点通用功能就往BaseActivity里写,可能等你的项目写完,你的基类也就几千行了,后面其他人来看,绝对想把你按在地上摩擦。这也是为什么你会发现哪怕官方的Activity都有什么FramgmentActivity,AppCompatActivity等之类的区分了,合理的分散功能比强行写在一起更容易让其他人使用。
封装技巧:
- 不要过度依赖继承
虽然上面已经建议了分散功能进行封装,但是,实践中并不建议基类层次超过三层的设计,结构过于复杂也会造成难于理解,不易维护。像上面的RefreshWebActivity已经是处于第三层封装了,所以不建议再继承他进行基类封装。不是过于复杂的功能,建议使用组合的方式来实现而不是仅仅通过继承,上面是以list功能为例,但是其实list的逻辑相对并不复杂,我们完全可以采用组合方式进行实现,这样,如果我们的DetailActivity如果也需要list,只需要进行组合就好。 - 控制基类层级
上面也说过了,尽量不要超出3层的基类封装,方便其他人协同开发和自己的日后维护。通常也不可能超过3层结构,如果你超出了,请确认下自己的架构设计。 - 封装高频代码
例如toast代码,本身很简单,也就一行的事,但是相对来说,它的使用频率算是比较高的,而且需要传的参数还是比较烦的,建议在基类封装出方法,这样以后想使用第三方toast库,也会很容易修改。 - 封装复杂代码
比如弹窗的代码,代码行数其实还是偏多的,并且通常来说,一个应用的弹窗样式还是比较统一的,没必要到处实例化,直接在基类进行,可以更方便修改。 - 不添加冗余代码
这里包括两点,一是,废弃的方法功能模块,及时清理掉,避免其他人使用时无意中引用到,造成以后清理时大面积报错,二是,不要添加某些小众功能逻辑到基类,比如某个特殊的业务逻辑功能,可能出现了3,5次的样子你就往基类里写,这样违背了面向对象的原则,并且以后你想直接复制这个基类到其他项目用又要删除这部分逻辑。
备注:上面主要是以activity为例,但是只要你拥有了基类的思想,不管是framgment还是adapter之类的,你都应该能举一反三了。
2.第三方库抉择
许多同学在使用第三方库的时候总是很纠结,不知道该用哪个,这里我简单介绍下我自己选择第三方库的一点点心得。
- star数
这点相信是大部分人都知道的一点,我们尽量避免使用github上只有个位数star的库,不是说个位数star的库都不好,而是对于萌新来说,别人的库怎么样,可能很难一眼看出来,这时候看star数就是最直观的了,至于那些优秀的个位数的star的库,还是交给老司机去发掘吧,大家就不要作死了。 - 查看issues详情
包括作者的解决效率,大家反馈的一些问题和bug - 更新频率
留意下作者的更新频率,如果是一两年没有更新的库,自己用之前最好能看下源码,是否出了bug有把握能修复,当然建议还是使用更新频率较高的库(说明作者持续在关注) - 文档
使用别人的库,文档真的很重要(遇到好多萌新都是不看文档,喜欢直接加群,去问别人,这种习惯真的要尽快改掉),不然遇到问题的话你可能只能联系作者或者自己默默去看源码了 - 使用难易度
有些库可能是针对一些老鸟进行封装的,所以使用起来会让萌新们感觉不适应,所以如果有替换的,可以考虑先放弃这个库,等以后水平上升了再换。
总结:不要只看star数,star数不代表一切,要知道某宝已经可以代刷star数了,遇到很多个star数差不多的库时,还是要综合上面几点多看看,自己评估一下用哪个
这次的分享就到此为止了,大家对我分享的东西有任何异议和问题的都欢迎提出。下次的分享暂内容还没想好,如果大家有什么想了解的,也可以在评论中提出,我会考虑下次分享一下,持续更新,欢迎大家关注