分析并实现Android中的MVC、MVP架构模式

架构是什么

架构是为了解决特定的问题而提出来的,而且它还有特定的规则,能够把整个应用的整体进行角色的划分。并且他还能够约定角色之间的联系沟通机制。

所以学习架构要带着以下三个问题去理解:

。架构解决了什么问题?

。架构模式是如何划分角色的?

。角色间是如何建立联系的?

在Android当中,经常被大家提及到就是MVC、MVP和MVVM。本文来分析一下MVC、MVP各自是怎么实现的,怎么写的,以及解决了什么问题而提出来的。

MVC

什么是MVC架构

MVC的话它本来不属于Android的架构模式,而是来自于web前端。在Android发展的前期照搬了前端这一套模式。

MVC模式就是Model、View和Controller。View的职责就是处理显示相关的逻辑以及接收用户行为。再把用户行为转发到Controller,Controller再根据请求去更新或者是获取Model层的数据。Controller更像是一个中转站或者是调度站。Model 负责管理数据、执行业务逻辑。MVC在前端的作用是为了分离数据和视图这两层,但是在Android上面它就不灵光了。

分析并实现Android中的MVC、MVP架构模式_第1张图片

在Android语境下,这里的Controller一般特指Activity和Fragment。而Model可以是 Java 类、数据库、网络请求或其他数据源,就是负责数据的读取操作的。而View的话一般来说是指XML布局文件。

代码实例




  

model

public class LoginModel {

    private static final String TAG = "LoginModel";

    private static final String URL = "https://api.cdnjs.com/libraries/jquery/3.5.1";

    private OnLoginListener mListener;

    public interface OnLoginListener {
        void onSuccess(String data);
        void onFail();
    }


    public void login(OnLoginListener listener) {
        mListener = listener;

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(URL)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure");
                if(null != mListener){
                    mListener.onFail();
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String message = response.body().string();
                Log.d(TAG, "onResponse:" + message);
                if(null != mListener){
                    mListener.onSuccess(message);
                }
            }
        });
    }
}

control


public class MvcActivity extends AppCompatActivity {

    private static final String TAG = "MvcActivity";

    private LoginModel model;

    private Button button;
    private TextView textView;

    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvc);

        button = findViewById(R.id.bt_mvc_login);
        textView = findViewById(R.id.tv_mvc_response);

        model = new LoginModel();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //请求数据
                model.login(new LoginModel.OnLoginListener() {
                    @Override
                    public void onSuccess(String data) {
                        //更新UI
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateView(data);
                            }
                        });
                    }

                    @Override
                    public void onFail() {

                    }
                });
            }
        });
    }

    private void updateView(String data) {
        textView.setText(data);
    }
}

上面的代码简单实现了在点击登录按钮后获取数据显示到 TextView。

分析并实现Android中的MVC、MVP架构模式_第2张图片

缺点

很明显,这种开发模式它的缺点就是当页面逻辑复杂时,容易导致Activity的代码膨胀。可能一个Activity当中它的代码量分分钟可以标到上千行。如果要修改某一处业务逻辑的话,有可能去找某个方法就要找半天,原因是Layout布局无法帮助Controller分担数据绑定的逻辑。

Activity虽然能够作为一个很称职的MVC Controller,但是作为一个类来说,它的职责太多了,需要实现的代码也太多了。首先从性能角度出发,Activity在使用期间会有大量的时间驻留在内存中,如果它的代码太多,就会导致性能问题。第二个也是最重要的,就是从分层架构的角度来说。如果某个层次过厚是不利于解耦的,我们就需要对这个层进行更细的拆分。

MVP

什么是MVP架构

后来为了解决Activity任务过于繁重,数据层与视图层交织在一起的问题,演化出来的MVP模式。它的主要特性就是让视图层和数据层分离。

分析并实现Android中的MVC、MVP架构模式_第3张图片

Activity 和 Fragment 视为View层,负责处理 UI和用户交互;

Presenter 为业务处理层,负责处理业务逻辑和发起数据的请求;

Model 层中包含着具体的数据请求,数据源。

这三者之间的关系是View调用Presenter,然后再调用Model去完成数据的请求动作。Model通过callback把数据回传给Presenter,然后Presenter再通过他持有的View接口,把数据回传到View层更新UI。

代码实例

将上面的mvc改成mvp

public class MvpActivity extends AppCompatActivity implements LoginContract.View{

    private static final String TAG = "MvpActivity";

    private LoginPresenter loginPresenter;

    private Button button;
    private TextView textView;

    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvc);

        button = findViewById(R.id.bt_mvc_login);
        textView = findViewById(R.id.tv_mvc_response);

        loginPresenter = new LoginPresenter();
        loginPresenter.attach(this);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                loginPresenter.getUserInfo();
            }
        });
    }

    @Override
    public void onResult(String data) {
        Log.d(TAG, "onResult data:" + data);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(data);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //释放
        loginPresenter.detach();
    }
}

presenter

public interface BaseView {
}

public class BasePresenter {
    protected IView view;
    /**
     * 绑定view
     * @param view
     */
    public void attach(IView view) {
        this.view = view;
    }
    public void detach() {
        view = null;
    }
}


public interface LoginContract {

    interface View extends BaseView {
        void onResult(String data);
    }

    //定义的每个方法都会在view结构当中存在与之相对应的回调方法
    abstract class Presenter extends BasePresenter {
        abstract void getUserInfo();
    }

}


public class LoginPresenter extends LoginContract.Presenter {

    private static final String TAG = "LoginPresenter";

    @Override
    void getUserInfo() {

        LoginModel model = new LoginModel();
        model.login(new LoginModel.OnLoginListener() {
            @Override
            public void onSuccess(String data) {
                view.onResult(data);
            }

            @Override
            public void onFail() {}
        });

    }
}

model

缺点

MVP这种开发模式对于简单的应用程序可能会显得过于复杂,MVP需要开发额外的Presenter类,可能增加开发工作量。为了实现MVP,通常需要定义大量的接口,这可能增加代码的复杂性。

总结

虽然MVP是MVC的优化后的产物,但还是各有利弊的。MVP解决了MVC在复杂项目中导致的Activity代码膨胀和维护难的问题。MVP复用代码的难度更低,实现方式替换起来更灵活。但是MVC的好处就是能够快速开发,在简单的页面上面使用起来非常的容易上手。所以我们到底要选择哪一种开发模式,需要看具体的场景。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

你可能感兴趣的:(Android,移动开发,架构,Android,移动开发,MVC,MVP,App架构)