一、MVC全名是Model View Controller
View:对应于布局文件
Model:业务逻辑和实体模型Controllor:对应于Activity
将业务逻辑、数据、界面显示 分离的方法来组织代码,将业务逻辑聚集到一个部件里面,在改进、和定制化界面及用户交互的时候,不用重新编写业务逻辑。其中M层处理数据、业务逻辑等;V层处理界面显示的结果;C层祈祷桥梁的作用,来控制V层和M层通信,并以此来达到业务逻辑层和视图显示分离开。
MVC for Android
在Android开发中,采用MVC的好处是便于UI界面的显示和业务逻辑、数据处理分离.
在Android开发中哪些代码充当 M、C、V呢?
M层:适合做一些业务逻辑处理,比如数据库的存储,网络请求、复杂的算法,耗时操作等都在model层处理。
V层:应用层 数据显示的部分,xml布局可以视为V层,用来显示model处理的数据。
C层:在Android中,Activity、Fragment处理用户交互的问题,因此可认为Activity是控制器,Avtivity读取V层数据(读取EditText控件数据)、控制用户输入,并向M层发送数据请求(eg:网络请求)
eg 搜索功能:C层的Activity获取EditText里的数据,然后向Model层发起网络请求,当Model模型处理数据结束后,通过回调通知C层数据树立完毕,View视图可以更新界面了,然后view调用相应方法更新UI。activity担当contronller完成了model和view之间的协调作用。
MVC使用总结
利用MVC设计模式,使得这个天气预报小项目有了很好的可扩展和维护性,当需要改变UI显示的时候,无需修改Contronller(控制器)Activity的代码和Model(模型)Model模型中的业务逻辑代码,很好的将业务逻辑和界面显示分离。
在Android项目中,业务逻辑,数据处理等担任了Model(模型)角色,XML界面显示等担任了View(视图)角色,Activity担任了Contronller(控制器)角色。contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。
Activity 控制器主要起到解耦的作用,将Model与View分离 ,虽然Activity祈祷分离的作用,但在Activity里有很多有关视图的Ui的相关代码,因此View视图与Activity Controller并不是完全分离的.
MVC应该如何设计?
mvc虽然只有三层,但并没有限制只能用三层,所以我们可以把 相对臃肿的 Controller里的逻辑代码抽取出来,形成可复用的模块、层次。
1、封装网络请求类
2、自定义控件封装
3、专门的存储类
通过代码的抽取,我们可以把ViewController 进一步拆分构造出 网络请求层、ViewModel 层、Service 层、Storage 层等其它类,来配合 Controller 工作,从而使 Controller 更加简单,我们的 App 更容易维护。
MVC 的优点
1、耦合性低,利用MVC框架,可以使得 View 层与Model层很好的分离,达到解耦的目的
2、可扩展性,由于耦合性低,扩展代码、添加需求可以减少代码的修改,减少BUG的概率
3、模块划分明确,利于代码的维护。
二、MVP模式
Model 依然是业务逻辑和实体模型
Presenter 负责完成View于Model间的交互
package com.cai.view; import com.cai.presenter.ILoginPresenter; import com.cai.presenter.ILoginPresenterImpl; import com.example.mvpdemo.R; import com.example.mvpdemo.R.id; import com.example.mvpdemo.R.layout; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.Toast; public class LoginActivity extends Activity implements ILoginView ,OnClickListener{ private EditText editUser; private EditText editPass; private Button btnLogin; private Button btnClear; ILoginPresenter loginPresenter; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); loginPresenter = new ILoginPresenterImpl(this); } private void findView() { // find view editUser = (EditText) this.findViewById(R.id.et_login_username); editPass = (EditText) this.findViewById(R.id.et_login_password); btnLogin = (Button) this.findViewById(R.id.btn_login_login); btnClear = (Button) this.findViewById(R.id.btn_login_clear); progressBar = (ProgressBar) this.findViewById(R.id.progress_login); btnLogin.setOnClickListener(this); btnClear.setOnClickListener(this); } @Override public void clearText() { editUser.setText(""); editPass.setText(""); } @Override public void onLoginResult(Boolean result, int code) { loginPresenter.setProgressVisiablity(View.INVISIBLE); if(result){ Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "登录失败,code="+code, Toast.LENGTH_SHORT).show(); } } @Override public void onSetProgressBarVisibility(int visibility) { progressBar.setVisibility(visibility); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_login_login: String userName = editUser.getText().toString(); String userWord = editUser.getText().toString(); if(TextUtils.isEmpty(userName) || TextUtils.isEmpty(userWord)){ return; } loginPresenter.setProgressVisiablity(View.VISIBLE); loginPresenter.login(userName, userWord); break; case R.id.btn_login_clear: loginPresenter.clear(); break; default: break; } } }
package com.cai.view; public interface ILoginView { public void clearText(); public void onLoginResult(Boolean result,int code); public void onSetProgressBarVisibility(int visibility); }
package com.cai.presenter; public interface ILoginPresenter { void clear(); void login(String name, String passwd); void setProgressVisiablity(int visiablity); }
package com.cai.presenter; import android.os.Handler; import android.os.Looper; import com.cai.model.User; import com.cai.view.ILoginView; public class ILoginPresenterImpl implements ILoginPresenter { private ILoginView loginView; private User user; private Handler handler; public ILoginPresenterImpl(ILoginView loginView) { this.loginView = loginView; setUser(); handler = new Handler(Looper.getMainLooper()); } private void setUser() { user = new User("mvp","mvp"); } @Override public void clear() { loginView.clearText(); } @Override public void login(String name, String passwd) { final int code = user.checkUserValidity(name, passwd); handler.postDelayed(new Runnable() { @Override public void run() { if(code != 0){ loginView.onLoginResult(false, -1); }else{ loginView.onLoginResult(true, 0); } } }, 3000); } @Override public void setProgressVisiablity(int visiablity) { loginView.onSetProgressBarVisibility(visiablity); } }
package com.cai.model; public class User { private String userName; private String userWord; public User() { super(); } public User(String userName, String userWord) { super(); this.userName = userName; this.userWord = userWord; } /** * @return the userName */ public String getUserName() { return userName; } /** * @param userName * the userName to set */ public void setUserName(String userName) { this.userName = userName; } /** * @return the userWord */ public String getUserWord() { return userWord; } /** * @param userWord * the userWord to set */ public void setUserWord(String userWord) { this.userWord = userWord; } public int checkUserValidity(String name, String passwd){ if (name==null||passwd==null||!name.equals(getUserName())||!passwd.equals(getUserWord())){ return -1; } return 0; } }