• 【Android


      提起MVP架构模式,大家可能首先想到的是它的“前辈”MVC模式。MVC由Model、View、Controller组成,请求从Controller进入后进行业务判断,然后交给Model或View进行处理。这本身没什么,但是应用在Android程序中时,大家就会发现,Activity既担任了Controller的角色进行业务筛选,又担任了View的角色进行界面展示,甚至有些时候还会担任Model的角色加载数据。这就使的Activity中的代码变得很多很长,而且功能杂乱,不便区分。怎么办呢?于是,MVP模式就诞生了。

      MVP由Model、View和Presenter组成,和MVC相似,MVP中的Model层也是用来加载数据的,View层也是用来展示界面的,MVP中独有的Presenter是用来连接Model和View两层,起到解耦的作用。下图展示了MVC模式和MVP模式的工作流程上的比较:

      从图中可以看到,MVP模式中的View层和Model层之间没有连线,即这两层之间没有直接的关联,它们之间的交互是通过Presenter来完成的,这样就实现的View和Model两层的解耦。具体的MVP内部的工作流程如下图所示:

      可以看到,用户首先在View层中进行操作,将用户动作传到Presenter中,Presenter将动作传递到Model中进行处理,然后将处理结果传回到Presenter,再由Presenter相应到View中。

      MVP模式的整体架构是通过接口来搭建的,我们需要一个整体的架构管理类Contract来管理Model、View、Presenter这三个接口,Model类、View类和Presenter类都分别实现这三个接口。Presenter中持有Model和View的引用,Presenter中的所有方法都会调用Model中对应的方法进行处理;Model中写实际代码;View是被Activity实现的,其中持有一个Presenter的引用,所有方法都会调用Presenter的对应方法。

      下面贴出一个简单的DEMO中的代码。

      DEMO的界面非常简单,只有一个按钮,当我们点击按钮的时候弹出一个Toast,就是这么一个简单的DEMO,我们尝试用MVP模式来搭建,编写。

      首先我们需要一个接口的统一管理类MainContract,这个类中包含了M、V、P三个接口,接口中定义抽象方法。这里我们只打算有一个方法,即按钮点击事件onButtonClicked()方法。代码如下:

    public class MainContract {
    
        interface View {
            void onButtonClicked(String text);
        }
    
        interface Model {
            void onButtonClicked(Context context, String text);
        }
    
        interface Presenter {
            void onButtonClicked(Context context, String text);
        }
    }

      有了接口之后,我们让M、V、P三层的具体类来实现这三个接口,这三个类分别是:M层对应MainModel,P层对应MainPresenter,V层对应MainActivity。

      我们来编写MainPresenter类中的代码,首先需要让它实现MainContract类中的Presenter接口,然后为它设置两个属性,一个是Model,一个是View,在构造方法中传入View,并初始化Model,最后实现Presenter接口中的方法并调用Model中的对应方法实现。MainPresenter类中的代码如下:

    public class MainPresenter implements MainContract.Presenter {
        private MainContract.Model model;
        private MainContract.View view;
    
        public MainPresenter(MainContract.View view) {
            this.view = view;
            this.model = new MainModel();
        }
    
        @Override
        public void onButtonClicked(Context context, String text) {
            model.onButtonClicked(context, text);
        }
    }

      接下来是MainModel类中的代码了。MVP中的所有具体逻辑实现的代码都是在Model层中编写的,因此在MainModel实现Model接口的onButtonClicked()方法中,我们按照需求弹出一个Toast即可。代码如下:

    public class MainModel implements MainContract.Model {
        @Override
        public void onButtonClicked(Context context, String text) {
            Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
        }
    }

      最后就是View层的编写了。上面说过,View层的实现类就是Activity,View层中需要持有一个Presenter的引用,View层中的所有操作都调用Presenter层中对应的方法,而Presenter层都是调用Model层的代码,因此View层就算是间接的调用了Model层的代码。MainActivity中的代码如下:

    public class MainActivity extends AppCompatActivity implements MainContract.View {
        private MainPresenter presenter = new MainPresenter(MainActivity.this);
    
        @InjectView(R.id.btn)
        protected Button button;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 初始化ButterKnife
            ButterKnife.inject(MainActivity.this);
        }
    
        @OnClick(R.id.btn)
        protected void click() {
            onButtonClicked("Button Clicked!!!!");
        }
    
        @Override
        public void onButtonClicked(String text) {
            presenter.onButtonClicked(MainActivity.this, text);
        }
    }

      到此为止,MVP的一个简单的DEMO就完成了。MVP只是一种思路,每个人都有每个人的理解,因此架构的搭建会有所不同,但整体的目标是不变的,那就是让Activity中的View层和Controller层分离开来,减少Activity中的代码。

      当然,MVP模式也有缺点,那就是每创建一个Activity,就需要再创建Contract、Model、Presenter三个类,会大大增加项目中的类的个数。

  • 相关阅读:
    使用灰层覆盖UI时,有事发生
    通过自定义ISAPI Filter来禁止敏感文件的访问
    静态链接库LIB和动态链接库DLL的区别 创建和示例
    深入剖析C++中的string类
    .net c# 序列化和反序列
    ASP.NET 状态服务 及 session丢失问题解决方案总结
    IWAM_账号的用途以及如何同步密码
    COM 组件设计与应用(一)起源及复合文件
    两种古老的WEB编程技术 CGI和ISAPI之间的区别
    Send MSMQ Messages Securely Across the Internet with HTTP and SOAP
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6210862.html
Copyright © 2020-2023  润新知