参考文章:

一.概念

框架模式和设计模式

  • 简单理解,框架面向一系列相同行为代码的重用,而设计模式面对的是一系列相同结构代码的重用;
  • 软件开发领域三种级别的重用

    • 内部重用,在同一应用中能公共使用的抽象块;
    • 代码重用,通用模块组合成库或工具类,及在多个应用和领域中都能重用;
    • 应用框架的重用,专用领域提供通用的或现成的基础结构,以获得最高级别的重用性;

      二.Mvc

      1.全称:Model—View—Controller

  • 模型(Model)-视图(View)-控制器(Controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界

面显示分离的方法组织代码;

  • 视图层(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的父类

      ```java public interface BaseModel { //用于跟activity或者fragment生命周期同步,在destroy做一些销毁操作 void onDestroy(); }
  1. <a name="hZST4"></a>
  2. ### 2.2.Callback:根据View或者Controller调用Model时回调的参数个数选择使用
  3. ```java
  4. public interface Callback1<T> {
  5. void onCallBack(T t);
  6. }
  7. public interface Callback2<T,P> {
  8. void onCallBack(T t,P p);
  9. }

2.3.具体的SampleModel

  1. public class SampleModel implements BaseModel{
  2. public void getUserInfo(String uid,Callback1<UserInfo> callback)
  3. {
  4. UserInfo userInfo= new HttpUtil<UserInfo>().get(uid);
  5. callback.onCallBack(userInfo);
  6. }
  7. @Override
  8. public void onDestroy() {
  9. }
  10. public class UserInfo
  11. {
  12. private int age;
  13. private String name;
  14. public int getAge() {
  15. return age;
  16. }
  17. public void setAge(int age) {
  18. this.age = age;
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. }
  27. }

2.4.SampleActivity:充当View和Controller

  1. public class SampleActivity extends AppCompatActivity {
  2. private SampleModel sampleModel;
  3. Button button;
  4. EditText textView;
  5. TextView tvAge,tvName;
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_sample);
  10. sampleModel=new SampleModel();
  11. button.setOnClickListener(new View.OnClickListener() {
  12. @Override
  13. public void onClick(View view) {
  14. getUserInfo(textView.getText().toString());
  15. }
  16. });
  17. }
  18. @Override
  19. protected void onDestroy() {
  20. super.onDestroy();
  21. sampleModel.onDestroy();
  22. }
  23. /**
  24. * 获取用户信息
  25. * @param uid
  26. */
  27. private void getUserInfo(String uid)
  28. {
  29. sampleModel.getUserInfo(uid, new Callback1<SampleModel.UserInfo>() {
  30. @Override
  31. public void onCallBack(SampleModel.UserInfo userInfo) {
  32. setDataToView(userInfo);
  33. }
  34. });
  35. }
  36. /**
  37. * 设置用户信息到view
  38. */
  39. private void setDataToView(SampleModel.UserInfo userInfo)
  40. {
  41. tvAge.setText(userInfo.getAge());
  42. tvName.setText(userInfo.getName());
  43. }
  44. }

3.Mvc总结

  • 3.1.控制器Activity
    • 主要起到的作用就是解耦,将视图View和Model进行分离;
    • View和Model在Activity中进行绑定或完成其它逻辑;
  • 3.2.优点

    视图View和Model进行分离,降低耦合度;

  • 3.3.缺点

    1. Activity类过于臃肿;
    2. View 无法组件化。View 是强依赖特定的 Model 的,如果需要把View 抽出来作为一个另外一个应用程序可复用的组件就困难了;

二.Mvp

1.特点

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

    2.Mvp代码示例

    2.1.BasePresenter:类似于MVC中的BaseModel

    1. public interface BasePresenter {
    2. void onDestroy();
    3. }

    2.2.BaseView:是所有View的父类

  • 将android中的view抽象化出来,只有跟view相关的操作都由baseView的实现类去完成。

  1. public interface BaseView<P extends BasePresenter> {
  2. void setPresenter(P presenter);
  3. }

2.3.Contract 契约类

  • 用于定义同一个界面的view的接口和presenter的具体实现。
  • 好处是通过规范的方法命名和注释可以清晰的看到整个页面的逻辑。

    1. public class SampleContract {
    2. public static class Presenter implements BasePresenter
    3. {
    4. public void getUserInfo(String uid,Callback1<SampleModel.UserInfo> callback)
    5. {
    6. SampleModel.UserInfo userInfo= new HttpUtil<SampleModel.UserInfo>().get(uid);
    7. callback.onCallBack(userInfo);
    8. }
    9. @Override
    10. public void onDestroy() {
    11. }
    12. }
    13. public interface View extends BaseView<Presenter>
    14. {
    15. void setDataToView(SampleModel.UserInfo userInfo);
    16. }
    17. }

    2.4.SampleActivity

  • SampleActivity实现了SampleContract.View只是作为View存在的 ```java 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) {

    1. super.onCreate(savedInstanceState);
    2. setContentView(R.layout.activity_sample);
    3. setPresenter(new SampleContract.Presenter());
    4. button.setOnClickListener(new View.OnClickListener() {
    5. @Override
    6. public void onClick(View view) {
    7. mPresenter.getUserInfo(textView.getText().toString(), new Callback1<SampleModel.UserInfo>() {
    8. @Override
    9. public void onCallBack(SampleModel.UserInfo userInfo) {
    10. setDataToView(userInfo);
    11. }
    12. });
    13. }
    14. });

    }

    @Override protected void onDestroy() {

    1. super.onDestroy();
    2. mPresenter.onDestroy();

    }

    @Override public void setDataToView(SampleModel.UserInfo userInfo) {

    1. tvAge.setText(userInfo.getAge());
    2. tvName.setText(userInfo.getName());

    }

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

}

  1. - mPresenterModelView之间交互的桥梁。
  2. - PresenterView相互持有
  3. <a name="hM5I4"></a>
  4. ## 3.Mvp总结
  5. - 通过引入接口BaseView,让相应的视图组件如ActivityFragment去实现BaseView,实现了视图层的独立;
  6. - 通过中间层Preseter实现了ModelView的完全解耦;
  7. - 优点
  8. > 1. mvp解决了mvcControllerView很难做到完全解耦的问题;
  9. > 2. View 可以进行组件化。在 MVP 当中,View 不依赖 Model。这样就可以让 View 从特定的业务场景中脱
  10. >
  11. 离出来,可以说 View 可以做到对业务逻辑完全无知。它只需要提供一系列接口提供给上层操作。这样就可
  12. > 以做高度可复用的 View 组件;
  13. - 缺点
  14. > 随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大。
  15. <a name="cvFqW"></a>
  16. # 三.mvvm
  17. - MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致;
  18. - 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然;
  19. - mvp中随着业务逻辑的增加,UI的改变多的情况下,会有非常多的跟UI相关的case,这样就会造成View的接口会很庞大。 mvvm解决了mvp的这个问题,通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行;
  20. - Activityxml layout充当ViewViewModel处理业务逻辑以及获取数据,弱化Model;
  21. <a name="C5Q5y"></a>
  22. ## 1.代码示例
  23. <a name="Y39qd"></a>
  24. ### 1.1.BaseViewModel
  25. - ViewMode层主要处理业务逻辑和获取数据,mViewDataBinding是通过View层传递过来。
  26. ```java
  27. public interface BaseViewModel {
  28. void onDestroy();
  29. }
  30. public abstract class AbstractViewModel<T extends ViewDataBinding> implements BaseViewModel {
  31. public T mViewDataBinding;
  32. public AbstractViewModel(T viewDataBinding)
  33. {
  34. this.mViewDataBinding=viewDataBinding;
  35. }
  36. @Override
  37. public void onDestroy() {
  38. mViewDataBinding.unbind();
  39. }
  40. }
  41. public class SampleViewModel extends AbstractViewModel<ActivitySampleMvvmBinding> {
  42. public SampleViewModel(ActivitySampleMvvmBinding viewDataBinding) {
  43. super(viewDataBinding);
  44. }
  45. public void getUserInfo(String uid, Callback1<SampleModel.UserInfo> callback)
  46. {
  47. //从网络或缓存获取信息
  48. SampleModel.UserInfo userInfo=new SampleModel.UserInfo();
  49. userInfo.setName("tom");
  50. userInfo.setAge(18);
  51. callback.onCallBack(userInfo);
  52. }
  53. }

2.Mvvm总结

  • 解决MVP中View层好多接口的问题,让View变得更简洁;
  • View的变动,自动反映在 ViewModel,反之亦然;
  • 看起来MVVM很好的解决了MVC和MVP的不足,但是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致。如果项目中打算用MVVM的话可以考虑使用官方的架构组件ViewModel、LiveData、DataBinding去实现MVVM(项目中已经使用,至今有一年多,待,待改善、整理到开源项目中);
  • 优点

    1. 提高可维护性。解决了 MVP 大量的手动 View 和 Model同步的问题,提供双向绑定机制。提高了代码的可维护性;
    2. 简化测试。mvp中View与Model的同步是交给Presenter去做的,在mvvm中,不需要手动去完成,交由databinding实现。Model变化,View会跟着Model同时变更,所以只需要保证Model的正确性,View就正确。大大减少了对 View 同步更新的测试;
  • 缺点

    1. 过于简单的图形界面不适用,或说牛刀杀鸡;
    2. 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高;
    3. 数据绑定的声明是指令式地写在 View 的模版当中的,这些内容是没办法去打断点 debug 的;

四.mvc/mvp/mvvm比较

  • 补充:Mvp不是一个标准化的模式,它有很多种实现方式,可以根据自己的需求或者认为对的方式去修正Mvp的实现方式,可以随Presenter的复杂程度变化。只要保证是通过Presenter将View和Model解耦;
  • 通过以上可以看出,Mvc的耦合度还是相对较高,View可以直接访问Model,导致三者之间形成回路;
  • Mvc与Mvp的主要区别:Mvp的View不能直接访问Model,需要通过Presenter发出请求,View与Model不直接通信;
  • Mvp和Mvvm的结构非常相似,唯一的区别是View和Model进行双向绑定,两者有一方变化会反应到另一方上。而Mvp和Mvvm的主要区别是Mvp的View更新需要通过Presenter,而Mvvm不需要;

    五.总结

  • 如果项目简单,没什么复杂性,未来改动也不大的话,那就不要用设计模式或者架构方法,只需要将每个模块封装好,方便调用即可,不要为了使用设计模式或架构方法而使用。

  • 对于偏向展示型的App,绝大多数业务逻辑都在后端,App主要功能就是展示数据,交互等,建议使用Mvvm。
  • 对于工具类或者需要写很多业务逻辑App,使用Mvp或者Mvvm都可。