总结了多年的移动开发经验,特别是在Android端的积累,之前认为从移动端APP谈架构,其实有点举大旗,由于大部份项目都在作业务理,且每每不是很大,并无多复杂的数据处理或高并发(只针对我的而言);而且长期认为架构这个词,用在Web端或者大型系统里比较好一点,好的架构好,意味系统更稳健、高效率, 更大致量。总之,有种大材小用的感受,然而,随着Android应用开发规模的扩大,客户端业务逻辑也愈来愈复杂,已然不是简单的数据展现了,APP也须要进行架构设计,拆分视图和数据,解除模块之间的耦合,提升模块内部的聚合度。html
对于开发人员来说,项目层面决定了如何搭建整个项目及划分模块,经常使用的Android程序结构:程序员
从程序结构看,架构在APP中无处不在,只是咱们不太关注,最简单的Demo其实都有涉及架构(一般是MVC)。从Android诞生至今,移动端的架构变动了不少次,从最初的MVC到MVP, 从冷门的Flutter(由RN引入到移动端)到Google的AAC/MVVM;好像架构的思想一直在变,但万变不离其中。下面将依次介绍MVC、MVP、MVVM这几种主流的架构设计,这里不会很深刻的分析这些架构的代码上有何区别,只是分析它们的设计思路,在项目中方便的选择适用的架构。算法
很是经典的架构,无论哪一个平台,都有这样的架构,好用又实惠。Android采用XML文件实现页面布局,经过Java在Activity中开发业务逻辑,这种开发模式实际上已经采用了MVC的思想,分离视图和控制器。MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。数据库
维基百科:
MVC模式最先由Trygve Reenskaug在1978年提出,是施乐帕罗奥多研究中心(XeroxPARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,而且使程序某一部分的重复利用成为可能。除此以外,此模式经过对复杂度的简化,使程序结构更加直观。软件系统经过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。专业人员能够经过自身的专长分组:
在Android编程中,View对应xml布局文件,Model对应实体模型(网络、数据库、I/O),Controller对应Activity业务逻辑,数据处理和UI处理。以下图所示:编程
//Model public interface WeatherModel { void getWeather(String cityNumber, OnWeatherListener listener); } ................ public class WeatherModelImpl implements WeatherModel { @Override public void getWeather(String cityNumber, final OnWeatherListener listener) { /*数据层操做*/ VolleyRequest.newInstance().newGsonRequest(http://www.weather.com.cn/data/sk/ + cityNumber + .html, Weather.class, new Response.Listener<weather>() { @Override public void onResponse(Weather weather) { if (weather != null) { listener.onSuccess(weather); } else { listener.onError(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { listener.onError(); } }); } } //Controllor(View)层 public class MainActivity extends ActionBarActivity implements OnWeatherListener, View.OnClickListener { private WeatherModel weatherModel; private EditText cityNOInput; private TextView city; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); weatherModel = new WeatherModelImpl(); initView(); } //初始化View private void initView() { cityNOInput = findView(R.id.et_city_no); city = findView(R.id.tv_city); ... findView(R.id.btn_go).setOnClickListener(this); } //显示结果 public void displayResult(Weather weather) { WeatherInfo weatherInfo = weather.getWeatherinfo(); city.setText(weatherInfo.getCity()); ... } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_go: weatherModel.getWeather(cityNOInput.getText().toString().trim(), this); break; } } @Override public void onSuccess(Weather weather) { displayResult(weather); } @Override public void onError() { Toast.makeText(this, 获取天气信息失败, Toast.LENGTH_SHORT).show(); } private T findView(int id) { return (T) findViewById(id); } }
例子分析:缓存
所以,在实际开发过程当中,纯粹做为View的各个XML文件功能较弱,Activity基本上都是View和Controller的合体,既要负责视图的显示又要加入控制逻辑,承担的功能不少,致使代码量很大。全部更贴切的目前常规的开发说应该是View-Model模式,大部分都是经过Activity的协调。性能优化
MVP是从MVC过渡而来,MVP架构由三部分组成:View负责显示,Presenter负责逻辑处理,Model提供数据。Android开发从MVC过渡到MVP,最主要的变化就是将Activity中负责业务逻辑的代码移到Presenter中,Activity只充当MVP中的View,负责界面初始化以及创建界面控件与Presenter的关联。网络
例如,MVC中,在业务逻辑稍微复杂一点的页面,Activity的代码超过一千是很容易的,但Activity并非一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操做请求,进而做出响应。随着界面及其逻辑的复杂度不断提高,Activity类的职责不断增长,以至变得庞大臃肿,那天然会想到进行拆分。这样拆分以后,Presenter承担了大量的逻辑操做,避免了Activity的臃肿。整个架构以下图所示:架构
//Model层 /** * 定义业务接口 */ public interface IUserBiz { public void login(String username, String password, OnLoginListener loginListener); } /** * 结果回调接口 */ public interface OnLoginListener { void loginSuccess(User user); void loginFailed(); } /** * 具体Model的实现 */ public class UserBiz implements IUserBiz { @Override public void login(final String username, final String password, final OnLoginListener loginListener) { //模拟子线程耗时操做 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //模拟登陆成功 if ("zhy".equals(username) && "123".equals(password)) { User user = new User(); user.setUsername(username); user.setPassword(password); loginListener.loginSuccess(user); } else { loginListener.loginFailed(); } } }.start(); } } //View public interface IUserLoginView { String getUserName(); String getPassword(); void clearUserName(); void clearPassword(); void showLoading(); void hideLoading(); void toMainActivity(User user); void showFailedError(); } //而后Activity实现这个这个接口: public class UserLoginActivity extends ActionBarActivity implements IUserLoginView { private EditText mEtUsername, mEtPassword; private Button mBtnLogin, mBtnClear; private ProgressBar mPbLoading; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_login); initViews(); } private void initViews() { mEtUsername = (EditText) findViewById(R.id.id_et_username); mEtPassword = (EditText) findViewById(R.id.id_et_password); mBtnClear = (Button) findViewById(R.id.id_btn_clear); mBtnLogin = (Button) findViewById(R.id.id_btn_login); mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading); mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.login(); } }); mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.clear(); } }); } @Override public String getUserName() { return mEtUsername.getText().toString(); } @Override public String getPassword() { return mEtPassword.getText().toString(); } @Override public void clearUserName() { mEtUsername.setText(""); } @Override public void clearPassword() { mEtPassword.setText(""); } @Override public void showLoading() { mPbLoading.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mPbLoading.setVisibility(View.GONE); } @Override public void toMainActivity(User user) { Toast.makeText(this, user.getUsername() + " login success , to MainActivity", Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show(); } } //Presenter public class UserLoginPresenter { private IUserBiz userBiz; private IUserLoginView userLoginView; private Handler mHandler = new Handler(); //Presenter必需要能拿到View和Model的实现类 public UserLoginPresenter(IUserLoginView userLoginView) { this.userLoginView = userLoginView; this.userBiz = new UserBiz(); } public void login() { userLoginView.showLoading(); userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final User user) { //须要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginFailed() { //须要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailedError(); userLoginView.hideLoading(); } }); } }); } public void clear() { userLoginView.clearUserName(); userLoginView.clearPassword(); } }
说明:并发
采用MVP明显的优势是避免了传统开发模式中View和Model耦合的状况,提升了代码可扩展性、组件复用能力、团队协做的效率以及单元测试的便利性。但也有一些缺点,好比:
因此,MVC到MVP简单说,就是增长了一个接口下降一层耦合。
MVVM 架构模式是微软在 2005 年诞生的,MVVM是Model-View-ViewModel的简称,它由三个部分组成,也就是 Model、View 和 ViewModel,其中视图模型(ViewModel)其实就是 PM 模式中的展现模型,在 MVVM 中叫作视图模型。从实际效果来看,ViewModel是View的数据模型和Presenter的结合,具体结构以下图所示:
说明:
View和Model之间经过Android Data Binding技术,实现视图和数据的双向绑定;ViewModel持有Model的引用,经过Model的方法请求数据;获取数据后,经过Callback(回调)的方式回到ViewModel中,因为ViewModel与View的双向绑定,使得界面得以实时更新。同时,界面输入的数据变化时,因为双向绑定技术,ViewModel中的数据得以实时更新,提升了数据采集的效率。
MVVM架构将Presenter更名为ViewModel,基本上与MVP模式彻底一致,惟一的区别是,它采用双向绑定(data-binding)View的变更,自动反映在 ViewModel,反之亦然,这就致使了咱们若是要完整的采用 MVVM 必须熟练的掌握 DataBinding 等基础组建,这就给咱们MVVM引入项目带了困难。
其实,MVC、MVP及MVVM没有绝对好坏,在软件编程过程当中,也不必非此即彼,脱离实际项目比较这些模式优劣毫无心义,各类模式都有优势和缺点,没有好坏之分。越高级的架构实现起来越复杂,须要更多的学习成本更多的人力,因此说技术选型关键是在你本身项目的特色,团队的水平,资源的配备,开发时间的限制,这些才是重点!可是很多团队本末倒置,把mvvm往本身的项目硬套。最重要的是让软件高内聚、低耦合、可维护、可扩展。
能够理解为移动端的架构思惟“MVX”,便是说按这个规则的分工,咱们不用费尽心思考虑狭义架构的分层问题了,就沿用Model-View-X来就能够(固然还能够本身加一些辅助的模块层)。
欢迎加入个人QQ交流群: 892872246 本群涉猎以下技术: 1.LiveDataBus 2.Google官方架构组件 3.Jetpack架构 4.饿了么通讯技术 5.OPenGL 6.音视频 7.人工智能 8.Python 9.性能优化 10.Flutter等