如何设计app架构?

在实际项目开发中,咱们曾无数次地吐槽刚接手的app太乱无法维护,内心曾有无数只草泥马走过。做为高素质时刻为他人着想的高端人才,咱们固然要为接手者铺好路,毕竟你们都不容易啊,程序员何苦难为程序员?因此咱们必定要注重app架构的优化,并且是在app刚开发时就应该考虑到架构的设计,那么应该如何去设计一个app的架构呢?做者给你们简单分享一下本身的心得,以及一些经验tips,但愿能对你们有所帮助。程序员


1、知足solid原则
json

在咱们面向对象的开发者看来,外物皆对象。其实一个app也不例外,这里面有不少的共通性,咱们也能够把它当作一个大的对象。那么咱们在设计一个app架构的时候就应该考虑到面向对象的五大solid原则,它们分别是:单一职责原则、开放封闭原则、里式替换原则、接口分离原则、依赖倒置原则。缓存

单一职责原则:一个类只作一种类型责任,当这个类须要承当其余类型的责任的时候,就须要分解这个类,这是解耦的重要步骤网络

开放封闭原则:对扩展开放,对修改关闭,好比使用代理模式架构

里式替换原则:当一个子类的实例应该可以替换任何其超类的实例时,它们之间才具备is-A关系,也就是说不能模糊化类的概念,类的设计必定要严谨app

接口分离原则:不要强迫使用不须要的接口,也就是说使用多个功能专注的接口比使用一个总接口要更好框架

依赖倒置原则:在须要依赖关系的地方尽可能依赖接口和抽象类,而不是具体类模块化


2、视图、数据、逻辑分离组件化

将视图、数据、逻辑分离分离有不少好处,好比便于维护、提高复用性、增长容错性等,这里经常使用的分离架构有MVC、MVP、MVVM等。若是不进行分离,最后的结果会是全部非静态布局代码都在Activity中,出现一个文件打天下的状况,最后维护起来兼职就是噩梦,这是咱们要避免的,好的app架构不该该出现这种状况。布局

MVC:获取数据的操做放到Model层,xml布局文件至关因而V层,Activity/Fragment至关因而C层,全部业务代码和界面都放到Controller中。虽然把获取数据抽象出了Model层,但C层依然太臃肿,这种模式通常只应用于很简单业务逻辑很少的界面,优势是写起来简单。

MVP:获取数据的操做放到Model层,Activity/Fragment此时至关因而V层,这是和MVC第一个不同的地方,第二个不同的地方是新增了Presenter来处理具体的业务逻辑,而V层只负责界面的显示相关逻辑,瞬间简洁了很多。当前MVP也有瑕疵,就是若是业务逻辑复杂的话,Presenter里要处理的内容过多,会致使Presenter很臃肿,不堪重负。

MVVM:获取数据的操做放到Model层,Activity/Fragment此时至关因而V层,而后新增了一个ViewModel层,经过DataBinding来将ViewModel跟布局文件进行绑定,从而将填充数据等逻辑直接废除,缺点是上手较慢一些,由于DataBinding仍是有必定学习成本的。

总结:在实际业务中具体使用哪种应该根据实际状况来定,若是是很简单的业务能够用MVC,通常是用MVP或者MVVM更好一些。


3、模块化架构

咱们应该将那些固定的模块进行抽离,将重要的模块进行解耦,因此必须对app中的代码进行模块化架构。常见的分层方式是分为7层,分别是硬件、操做系统、JNI、Base、网络、common、业务模块。当前这并不表明最优,可是也是比较常见的划分模块的方式。前面3个是底层模块这里就不阐述,下面说一下其余4个模块的内容和依赖关系。

Base:存放接口抽象类util类等基础的类,只要后期稳定了基本都不须要修改,可是牵一发动全身,通常由架构师或高级程序员来维护。Base就是最基本的模块,不依赖任何模块。

网络:这里是存放网络请求用到的一些类,好比网络框架代码、网络错误处理、添加固定header等,网络层依赖于base层,由于须要base层的一些基类

common:这里是存放各个业务模块都须要用到的类,常见的好比自定义view,能够在各个业务中复用的时候,能够存放到common层,common模块也依赖于base模块。

业务模块:实际的业务代码,依赖于common层和网络层,这里可使用组件化进行架构。因为组件化通讯比较复杂,具体后面会从新开一篇文章来详细说明。


4、重要数据内置和缓存

为了提高app在用户没网时的体验,在主流app中都会对数据进行缓存,在没网时显示缓存内容。而后在下次打开app或者先后台切换时更改缓存文件,达到更新的目的。也能够在界面显示时对界面进行更新,不过这样作可能会形成闪烁,很是影响用户体验,这里不推荐这种作法。

除此以外,为了防止新用户首次打开app就出现网络不佳的状况,咱们须要对重要数据进行内置,若是是列表咱们能够只内置一页数据。内置方式就是将数据以json的形式保存在asset下的文件里,而后运行时从asset下读取而且解析到内存中使用。内置内容通常只在第一次打开app时可能会用到,后面都是用缓存内容进行显示。


5、其余经验之谈

1.咱们能够在网络层写好,debug模式下自动打印出请求参数和返回值,方便开发时进行调试

2.网络请求时不一样的错误须要进行区分处理,而且向服务端打点,方便查找问题

3.base层应该支持在实际界面关闭时取消网络请求,防止作无用操做,节省内存开销

4.若是是MVVM业务结构的话,须要注意的是若是ViewModel持有view的对象时应该使用弱引用的方式,而后应该在view关闭的生命周期中对该持有进行清除操做,防止内存泄漏

5.在须要切换同一布局的内容显示时,为了不重复的显示隐藏判断操做,可使用TipsView

6.在一些简单app中没有splash倒计时功能,此时要解决打开app白屏问题的话,咱们仍然能够新建一个SplashActivity,此时能够在splash的onpause中关闭当前页面


最后:以上几点是很重要的经验,但也不表明考虑了这些点就是最优秀的架构了。实际项目远比理论复杂,因此咱们须要作的是借鉴别人的经验,来解决本身的实际问题。做者之后有其余的经验也会更新上去,但愿能给你们带来一些帮助。