MVC
MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。
Model(模型) - 模型代表一个存取数据的对象。它也可以带有逻辑,在数据变化时更新控制器。
View(视图) - 视图代表模型包含的数据的可视化。
Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。
实例实现:
创建一个作为模型的 Student
对象
StudentView
是一个把学生详细信息输出到控制台的视图类,StudentController
是负责存储数据到 Student
对象中的控制器类,并相应地更新视图 StudentView
。
MVCPatternDemo
演示类使用 StudentController
来演示 MVC 模式的用法。
创建Module
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建视图
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo){
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
创建控制器
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view){
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentRollNo(String rollNo){
model.setRollNo(rollNo);
}
public String getStudentRollNo(){
return model.getRollNo();
}
public void updateView(){
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
使用 StudentController 方法来演示 MVC 设计模式的用法
public class MVCPatternDemo {
public static void main(String[] args) {
//从数据库获取学生信息
Student model=getItem();
//创建第一个视图,将学生信息更新到控制台
StudentView view=new StudentView();
StudentController controller=new StudentController(model,view);
controller.updateView();
//更新模型数据
controller.setStudentName("1008611");
controller.updateView();
}
private static Student getItem(){
Student stu1=new Student();
stu1.setName("alibaba");
stu1.setRollNo("001");
return stu1;
}
}
MVP
MVP和MVC最大的区别是P层代替了以前的C层,控制的不再是具体的实现而是接口,这样不管是多人开发还是频繁的UI更改,都不会影响P层,只要P和V层的接口不变,UI的改动只需要更改V层的实现而已,P层的实现都不需要改,逻辑层和视图层完全分离,
使用用户登录这个例子:
android已经很好的把P层和V层分开了,我们写的xml相当于V层,Activity相当于P层
public interface ICallback{
void receive(boolean success);
}
public class LoginModel{
public void login(String name,String password,ICallback callback){
WebApi.login(name,password,callback);
}
}
public class LoginActivity extends Activity{
private LoginModel mLoginModel;
private EditText mUserNameEt;
private EditText mPasswordEt;
private Button mSubmitBtn;
public void onCreate(......){
mLoginModel = new LoginModel(...);
mSubmitBtn.setOnClickListener(new OnClickListener(View view){
mLoginModel.login(mUserNameEt.get...,mPasswordEt.get...,new ICallback(){
public void receive(boolean success){
if(success){
startActivity(new Intent(this,MainActivity.class));
finish();
} else {
Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
}
}
});
});
}
}
修改成MVP模式:
public interface ILoginContract {
public interface ILoginModel{
public void login(String name,String password,ICallback callback);
}
public interface ILoginPresenter{
public void login(String name,String password);
}
public interface ILoginView{
public void showDialog();
public void dismissDialog();
public void showToast(String message);
public void navigateToMain();
}
}
public class PresenterImpl implements ILoginPresenter,ICallback{
private ILoginView mLoginView;
private ILoginModel mLoginModel;
public PresenterImpl(ILoginView loginView){
this.mLoginView = loginView;
this.mLoginModel = new LoginModelImpl();
}
public void login(String name,String password){
if(isEmpty(name)||isEmpty(password)){
this.mLoginView.showToast("用户名或密码不能为空");
return;
}
this.mLoginModel.login(name,password,this);
}
public void receive(boolean success){
if(success){
this.mLoginView.navigateToMain();
}else{
this.mLoginView.showToast("登录失败");
}
}
private boolean isEmpty(String text){
return text==null||"".equals(text)?true:false;
}
}
public class LoginActivity extends Activity implements ILoginView{
private IPresenter mPresenter;
private EditText mUserNameEt;
private EditText mPasswordEt;
private Button mSubmitBtn;
public void onCreate(......){
mPresenter = new PresenterImpl(this);
mSubmitBtn.setOnClickListener(new OnClickListener(View view){
mPresenter.login(mUserNameEt.getText().toString(),
mPasswordEt.getText().toString());
});
}
public void showDialog(){
//显示一个转圈的dialog;
}
public void dismissDialog(){
//隐藏转圈的dialog;
}
public void showToast(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
public void navigateToMain(){
startActivity(new Intent(this,MainActivity.class));
finish();
}
}
MVP相比于MVC的优势:
●分离了视图逻辑和业务逻辑,降低了耦合。
●Activity只处理生命周期的任务, 代码变得更加简洁。
●视图逻辑和业务逻辑分别抽象到了View和Presenter的接口中去,提高代码的可阅读性。
●Presenter被抽象成接口, 可以有多种具体的实现,所以方便进行单元测试。
●把业务逻辑抽到Presenter中去 ,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM
MVVM
与MVP类似,利用数据绑定(Data Binding)、 依赖属性(Dependency Property)、 命令(Command)、 路由事件(Routed Event)等新特性,打造了一个更加灵活高效的架构。
MVVM相比于MVP的优势:
- 在常规的开发模式中,数据变化需要更新UI的时候,需要先获取UI控件的引用,然后再更新UI,获取用户的输入和操作也需要通过UI控件的引用,但在MVVM中,这些都是通过数据驱动来自动完成的,数据变化后会自动更新UI,U的改变也能自动反馈到数据层,数据成为主导因素。这样MVVM层在业务逻辑处理中只要关心数据,不需要直接和UI打交道,在业务处理过程中简单方便很多。