MVP模式

本文详细探讨了MVP模式在Android应用程序开发中的使用,包括其基本概念、优点以及如何在实际项目中实现和维护。通过MVP模式,开发者可以更好地分离视图、业务逻辑和数据,提高代码的可测试性和可维护性。文章适合对Android编程有一定基础并希望提升架构理解的读者。
摘要由CSDN通过智能技术生成

转载请标明出处:

http://blog.csdn.net/mollyxiong/article/details/54925663

本文出自:【MollyShong博客】



一个简单的发送内容的demo 先上效果图




MVP模式的结构



一、什么是MVP模式?
    分离view 与 model 层的功能,使得程序更加清晰 提高分离 解耦性,减轻activity的工作量 将业务代码单独抽取出来,各自负责各自层应该做的事情。简单一句话说就是基于MVC模式演变而来,提高代码结构清晰度,提高程序解耦性可维护性的模式。
    接下来我们具体梳理下MVP究竟是什么
    M 对应的Model 数据层,负责操作、获取数据
    V 对应的是View 也就是Activity层,负责UI、与用户进行交互
    P Presenter 就是我们要分离的业务逻辑层,连接view和model层,处理业务逻辑。

二、为什么要用MVP模式?
    Android开发不同于JavaWeb开发的是利用MVC模式 使得控制器和展示层完全分离,但是Android中activity有控制器也有view做的事情,如果把布局文件单独分成view层,几乎就没有做什么事情,而activity还承担了部分view层的工作,到最后需求越来越多,activity也会越来也胖。所以在Android开发中可以使用MVP模式来清晰的分离各自层的工作。同样也利于单元测试。

三、MVP模式怎么用?
    view层专门负责UI及用户交互
    Persenter层负责所有的业务逻辑的处理
    Model层负责数据的获取、操纵
    各个层单独分离,用层与层之间用接口交互

下面我们来看一个简单的Demo
    Acitivity  也就是view层 实现了ViewInterface接口,分离业务逻辑

public class MainActivity extends AppCompatActivity implements ViewInterface, View.OnClickListener {


    private EditText content;
    private EditText author;
    private Button send;
    private Button clean;
    private ProgressBar loading;

    private PresenterImpl presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    public void initView(){
        content = (EditText) findViewById(R.id.content);
        author = (EditText) findViewById(R.id.author);
        loading = (ProgressBar) findViewById(R.id.loading);
        send = (Button) findViewById(R.id.send);
        clean = (Button) findViewById(R.id.clean);
        send.setOnClickListener(this);
        clean.setOnClickListener(this);

        presenter = new PresenterImpl(this);
    }

    /**
     * 显示和隐藏进度条
     */
    @Override
    public void showProgressBar() {
        loading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgressBar() {
        loading.setVisibility(View.GONE);
    }

    /**
     * 发送是成功还是失败各自需要做的事情
     */
    @Override
    public void sendSuccess() {
        Toast.makeText(this,"发送成功!",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void sendFailed() {
        Toast.makeText(this,"发送失败!",Toast.LENGTH_SHORT).show();
    }

    /**
     * 清除发送内容
     */
    @Override
    public void cleanContent() {
        content.setText("");
    }

    @Override
    public void cleanAuthor() {
        author.setText("");
    }

    /**
     * 获取内容和作者
     */
    @Override
    public String getContent() {
        return content.getText().toString().trim();
    }
    @Override
    public String getAuthor() {
        return author.getText().toString().trim();
    }

    /**
     * Called when a view has been clicked.
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        switch( v.getId()){
            case R.id.send:
                presenter.send();
                break;
            case R.id.clean:
                presenter.clean();
                break;
        }
    }

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

ViewInterface

/**
 * Created by Administrator on 2017/2/7.
 * view 层的接口,定义view 的所有动作  view通常是指activity 让activity去实现本接口
 * view 和 presenter 互相持有引用
 */

public interface ViewInterface {

    /**
     * 显示和隐藏进度条
     */
    public void showProgressBar();
    public void hideProgressBar();

    /**
     * 发送是成功还是失败各自需要做的事情
     */
    public void sendSuccess();
    public void sendFailed();

    /**
     * 清除发送内容
     */
    public void cleanContent();
    public void cleanAuthor();

    /**
     * 获取内容和作者
     */
    public String getContent();
    public String getAuthor();
}

业务逻辑层

/**
 * Created by Administrator on 2017/2/7.
 *
 * 控制 业务层,处理所有的业务逻辑,连接view 和 model
 */

public interface PresenterInterface {

    public void send();
    public void destroy();
    public void clean();
}

从view层获取数据 ,做完相应的业务处理,把事情交给model校验数据,返回结果,根据结果控制view做出相应的UI处理
/**
 * Created by Administrator on 2017/2/7.
 */

public class PresenterImpl implements PresenterInterface {


    ViewInterface viewInterface;
    ModelImpl model;
    private Handler mHandler = new Handler();

    public PresenterImpl() {
    }

    public PresenterImpl(ViewInterface viewInterface) {
        this.viewInterface = viewInterface;
        model = new ModelImpl();
    }

    @Override
    public void send() {
        //显示进度条
        viewInterface.showProgressBar();
        model.send(viewInterface.getContent(), viewInterface.getAuthor(), new ModelInterface.OnSendLinterer() {
            @Override
            public void sendSuccess() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        viewInterface.sendSuccess();
                        viewInterface.hideProgressBar();
                    }
                });
            }

            @Override
            public void sendFailed() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        viewInterface.sendFailed();
                        viewInterface.hideProgressBar();
                    }
                });
            }
        });
    }

    @Override
    public void destroy() {
        viewInterface = null;
        model.destory();
        model = null;
    }


    @Override
    public void clean() {
        viewInterface.cleanAuthor();
        viewInterface.cleanContent();
    }
}

数据层
/**
 * Created by Administrator on 2017/2/7.
 *
 * 数据层,做的事情就是为Presenter层提供数据
 */

public interface ModelInterface {


    interface OnSendLinterer{
        void sendSuccess();
        void sendFailed();
    }
    public void send(String content, String author, OnSendLinterer onSendLinterer);
}

发送数据请求发送内容是否成功,这里用的是模拟
/**
 * Created by Administrator on 2017/2/7.
 */

public class ModelImpl implements ModelInterface {

    private ExecutorService executorService ;

    public ModelImpl(){
        //获取一个线程池 根据 虚拟机可用的处理器的最大数量 +1 定义线程池大小
        executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
    }


    @Override
    public void send(String content, String author,final OnSendLinterer onSendLinterer) {
        executorService.execute(new Runnable() {
            /**
             * When an object implementing interface <code>Runnable</code> is used
             * to create a thread, starting the thread causes the object's
             * <code>run</code> method to be called in that separately executing
             * thread.
             * <p>
             * The general contract of the method <code>run</code> is that it may
             * take any action whatsoever.
             *
             * @see Thread#run()
             */
            @Override
            public void run() {
                //模拟网络请求的耗时操作
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //随机boolean 模拟发送成功或失败
                Random random = new Random();
                if( random.nextBoolean() ){
                    onSendLinterer.sendSuccess();
                }else{
                    onSendLinterer.sendFailed();
                }
            }
        });
        //不再接受新的任务
//        executorService.shutdown();
        /*try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }*/
    }
    public void destory(){
        executorService = null;
    }
}

项目的结构
 

四、MVP模式什么时候用?
    可能有朋友会觉得MVP是为了模式而模式,开发中类变得多了,感觉还更加复杂了。我们知道,当需求过多过于复杂的时候,activity的代码量就会越来越多,可能一个activity中会有几千行代码,极大的影响了后期的维护和开发的成本。如果用上MVP就能极大限度的将activity中展示 业务处理 数据存取单独分离出来,虽然类文件增加了不少,但是整体来看程序和代码的结构还是很清晰的。所以,应用层开发的项目个人觉得使用MVP都是比较合适的。

使用MVP模式,建议按功能分包,利于后面的维护和开发

最后附上Demo的下载链接: github
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值