当前位置:网站首页>Mvc, Mvp and Mvvm

Mvc, Mvp and Mvvm

2022-08-04 00:20:00 slow cavalry

一.概念

1.Framework patterns and design patterns

  • 简单理解,Frameworks are geared towards the reuse of a set of code that behaves the same,Design patterns, on the other hand, face the reuse of a series of code with the same structure;
  • Three levels of reuse in software development
    • 内部重用,An abstract block that can be used publicly in the same application;
    • 代码重用,Common modules are grouped into libraries or utility classes,and reusable across multiple applications and domains;
    • 应用框架的重用,Specialized domains provide general-purpose or off-the-shelf infrastructure,以获得最高级别的重用性;

二.Mvc

1.全称:Model–View–Controller

  • 模型(Model)-视图(View)-控制器(Controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界
    The face shows the separation of methods to organize the code;
  • 视图层(View)
    • 对应于Xml布局文件和Java代码动态View部分;
  • 控制层(Controller)
    • MVC中Android的控制层是由Activity来承担的;
    • Activity本来主要是作为初始化页面,展示数据的操作,但是因为XML视图功能太弱,所以Activity既要负责视图的显示又要加入控制逻辑,承担的功能过多;
  • 模型层(Model)
    • 针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作;
  • 通信方式(所有通信都是单向的)
    • View 传送指令到 Controller;
    • Controller 完成业务逻辑后,要求 Model 改变状态;
    • Model 将新的数据发送到 View,用户得到反馈;

2.mvc在android中的代码实现

2.1.BaseModel,所有业务逻辑model的父类

public interface BaseModel {
    
    //用于跟activity或者fragment生命周期同步,在destroy做一些销毁操作
    void onDestroy();
}

2.2.Callback:根据View或者Controller调用Model时回调的参数个数选择使用

public interface Callback1<T> {
    
    void onCallBack(T t);
}
public interface Callback2<T,P> {
    
    void onCallBack(T t,P p);
}

2.3.具体的SampleModel

public class SampleModel  implements BaseModel{
    

    public void  getUserInfo(String uid,Callback1<UserInfo> callback)
    {
    

        UserInfo userInfo= new HttpUtil<UserInfo>().get(uid);
        callback.onCallBack(userInfo);

    }

    @Override
    public void onDestroy() {
    

    }

    public class UserInfo
    {
    
        private int age;
        private String name;

        public int getAge() {
    
            return age;
        }

        public void setAge(int age) {
    
            this.age = age;
        }

        public String getName() {
    
            return name;
        }

        public void setName(String name) {
    
            this.name = name;
        }
    }
}

2.4.SampleActivity:充当View和Controller

public class SampleActivity extends AppCompatActivity {
    
    private SampleModel sampleModel;
    Button button;
    EditText textView;
    TextView tvAge,tvName;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample);
        sampleModel=new SampleModel();
        button.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View view) {
    
                getUserInfo(textView.getText().toString());
            }
        });

    }

    @Override
    protected void onDestroy() {
    
        super.onDestroy();
        sampleModel.onDestroy();
    }

    /** * 获取用户信息 * @param uid */
    private void getUserInfo(String uid)
    {
    
        sampleModel.getUserInfo(uid, new Callback1<SampleModel.UserInfo>() {
    
            @Override
            public void onCallBack(SampleModel.UserInfo userInfo) {
    
                setDataToView(userInfo);
            }
        });
    }

    /** * 设置用户信息到view */
    private void setDataToView(SampleModel.UserInfo userInfo)
    {
    
        tvAge.setText(userInfo.getAge());
        tvName.setText(userInfo.getName());
    }

}

3.Mvc总结

  • 3.1.控制器Activity
    • The main function is decoupling,将视图View和Model进行分离;
    • View和Model在ActivityBind or complete other logic in;
  • 3.2.优点
    视图View和Model进行分离,降低耦合度;
  • 3.3.缺点
    • Activity类过于臃肿;
    • View 无法组件化.View 是强依赖特定的 Model 的,如果需要把View 抽出来作为一个另外一个应用程序可复用的组件就困难了;

二.Mvp

1.特点

  • MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向;
  • 各部分之间的通信,都是双向的;
  • View 与 Model 不发生联系,都通过 Presenter 传递;
  • View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里;

2.Mvp代码示例

2.1.BasePresenter:类似于MVC中的BaseModel

public interface BasePresenter {
    
    void onDestroy();
}

2.2.BaseView:是所有View的父类

  • 将android中的viewabstracted out,只有跟view相关的操作都由baseView的实现类去完成.
public interface BaseView<P extends BasePresenter> {
    
    void setPresenter(P presenter);
}

2.3.Contract 契约类

  • 用于定义同一个界面的view的接口和presenter的具体实现.
  • 好处是通过规范的方法命名和注释可以清晰的看到整个页面的逻辑.
public class SampleContract {
    
    public static class Presenter implements BasePresenter
    {
    
        public void  getUserInfo(String uid,Callback1<SampleModel.UserInfo> callback)
        {
    
            SampleModel.UserInfo userInfo= new HttpUtil<SampleModel.UserInfo>().get(uid);
            callback.onCallBack(userInfo);
        }

        @Override
        public void onDestroy() {
    

        }
    }
    public interface View extends BaseView<Presenter>
    {
    
         void setDataToView(SampleModel.UserInfo userInfo);
    }
}

2.4.SampleActivity

  • SampleActivity实现了SampleContract.View只是作为View存在的
public class SampleActivity extends AppCompatActivity implements SampleContract.View{
    
    private  SampleContract.Presenter mPresenter;
    Button button;
    EditText textView;
    TextView tvAge,tvName;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample);
        setPresenter(new SampleContract.Presenter());

        button.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View view) {
    
                mPresenter.getUserInfo(textView.getText().toString(), new Callback1<SampleModel.UserInfo>() {
    
                    @Override
                    public void onCallBack(SampleModel.UserInfo userInfo) {
    
                        setDataToView(userInfo);
                    }
                });
            }
        });

    }

    @Override
    protected void onDestroy() {
    
        super.onDestroy();
        mPresenter.onDestroy();
    }

    @Override
    public void setDataToView(SampleModel.UserInfo userInfo) {
    
        tvAge.setText(userInfo.getAge());
        tvName.setText(userInfo.getName());
    }


    @Override
    public void setPresenter(SampleContract.Presenter presenter) {
    
        mPresenter=presenter;
    }
}

3.Mvp总结

  • 通过引入接口BaseView,让相应的视图组件如Activity,Fragment去实现BaseView,实现了视图层的独立;
  • 通过中间层Preseter实现了Model和View的完全解耦;
  • 优点
    • mvp解决了mvc的Controller和ViewIt is difficult to completely decouple the problem;
    • View 可以进行组件化.在 MVP 当中,View 不依赖 Model.这样就可以让 View Detach from a specific business scenario
      离出来,可以说 View 可以做到对业务逻辑完全无知.它只需要提供一系列接口提供给上层操作.这样就可
      to be highly reusable View 组件;
  • 缺点
    随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大.

三.Mvvm

  • MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致;
  • 唯一的区别是,它采用双向绑定(Mvvm的核心data-binding):View的变动,自动反映在 ViewModel,反之亦然;
  • mvpWith the increase of business logic,UI的改变多的情况下,会有非常多的跟UI相关的case,这样就会造成View的接口会很庞大. mvvm解决了mvp的这个问题,通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行;
  • Activity和xml layout充当View,ViewModel处理业务逻辑以及获取数据,弱化Model;

1.代码示例

1.1.BaseViewModel

  • ViewMode层主要处理业务逻辑和获取数据,mViewDataBinding是通过View层传递过来.
public interface BaseViewModel {
    
    void onDestroy();
}

public abstract class AbstractViewModel<T extends ViewDataBinding> implements BaseViewModel {
    
    public T mViewDataBinding;
    public AbstractViewModel(T viewDataBinding)
    {
    
        this.mViewDataBinding=viewDataBinding;
    }

    @Override
    public void onDestroy() {
    
        mViewDataBinding.unbind();
    }
}

public class SampleViewModel extends AbstractViewModel<ActivitySampleMvvmBinding> {
    

    public SampleViewModel(ActivitySampleMvvmBinding viewDataBinding) {
    
        super(viewDataBinding);
    }

    public  void getUserInfo(String uid, Callback1<SampleModel.UserInfo> callback)
    {
    
        //从网络或缓存获取信息
        SampleModel.UserInfo userInfo=new SampleModel.UserInfo();
        userInfo.setName("tom");
        userInfo.setAge(18);
        callback.onCallBack(userInfo);
    }
}

2.Mvvm总结

  • 解决MVP中View层好多接口的问题,让View变得更简洁;
  • View的变动,自动反映在 ViewModel,反之亦然;
  • 看起来MVVM很好的解决了MVC和MVP的不足,但是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致.如果项目中打算用MVVM的话可以考虑使用官方的架构组件ViewModel、LiveData、DataBinding去实现MVVM(项目中已经使用,至今有一年多,待,待改善、Organized into open source projects);
  • 优点
    • 提高可维护性.解决了 MVP 大量的手动 View 和 Model同步的问题,提供双向绑定机制.提高了代码的可维护性;
    • 简化测试.mvp中View与ModelThe synchronization is handed overPresenter去做的,在mvvm中,No need to do it manually,交由databinding实现.Model变化,View会跟着Model同时变更,所以只需要保证Model的正确性,View就正确.大大减少了对 View 同步更新的测试;
  • 缺点
    • 过于简单的图形界面不适用,或说牛刀杀鸡;
    • 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高;
    • 数据绑定的声明是指令式地写在 View 的模版当中的,这些内容是没办法去打断点 debug 的;

四.Mvc/Mvp/Mvvm比较

  • MvpNot a standardized pattern,它有很多种实现方式,You can modify it according to your needs or the way you think is rightMvp的实现方式,可以随Presenterchanges in complexity.Just make sure to passPresenter将View和Model解耦;
  • 通过以上可以看出,MvcThe coupling is still relatively high,View可以直接访问Model,lead to the formation of a loop between the three;
  • Mvc与Mvp的主要区别:Mvp的View不能直接访问Model,需要通过Presenter发出请求,View与Model不直接通信;
  • Mvp和Mvvm的结构非常相似,唯一的区别是View和Model进行双向绑定,Changes in one of the two will be reflected in the other.而Mvp和Mvvm的主要区别是Mvp的View更新需要通过Presenter,而Mvvm不需要;

五.总结

  • The project is simple,维护性不高,Package the module,No architecture or design patterns are required,只需要将每个模块封装好,方便调用即可,不要为了使用设计模式或架构方法而使用;
  • Small projects can be usedMvc;
  • Focus on data presentation and interaction(对于偏向展示型的App,绝大多数业务逻辑都在后端,App主要功能就是展示数据,交互等),建议采用Mvvm;
  • 大型项目,Business complex adoptionMvp;
  • 对于工具类或者需要写很多业务逻辑App,Mvp或者Mvvm都可,The architecture can be flexibly selected according to the specific project(如:混合架构)等;

六.参考

原网站

版权声明
本文为[slow cavalry]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/216/202208040012453142.html