rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • MVC

MVC

介绍1

1. MVC介绍

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种框架模式。

Model:模型层,负责处理数据的加载或存储。 View:视图层,负责界面数据的展示,与用户进行交互。 Controller:控制器层,负责逻辑业务的处理。

1.1 作用

将业务逻辑、数据、界面分离的一种代码组织方式,修改界面时无需去修改业务逻辑。

1.2 流程

1.View接受用户的请求,然后将请求传递给Controller。 2.Controller进行业务逻辑处理后,通知Model去更新。 3.Model数据更新后,通知View去更新界面显示。

1.3 关系

一个模型可以有多个视图,一个视图可以有多个控制器,一个控制器也可以有多个模型。

2. MVC例子实现

Android中一般布局的XML文件就是View层,Activity则充当了Controller的角色。

下面举个简单的例子来实现,点击按钮对数字+1然后重新显示出来。

2.1 Model层

创建一个数据模型,能够保存一个数字,并有一个更新的方法,数据更新完后会通知UI去更改显示的内容。

public class NumModel {
    private int num = 0;

    public void add(ControllerActivity activity) {
        num = ++num;//更新数据
        activity.updateUI(num + "");//更新UI
    }

}

2.2 View层

View层在Android中对应的就是布局的XML文件。 activity_controller.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"/>

    <Button
        android:id="@+id/btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击+1"/>
</LinearLayout>

2.3 Controller层

Android中一般由Activity来充当Controller。Controller一方面接收来自View的事件,一方面通知Model处理数据。

public class ControllerActivity extends Activity {

    private TextView mTextView;
    private Button mButton;
    private NumModel mNumModel;

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

        mTextView = findViewById(R.id.tv_show);
        mButton = findViewById(R.id.btn_add);
        mNumModel = new NumModel();
        
        mButton.setOnClickListener(new View.OnClickListener() {//接收来自View的事件
            @Override
            public void onClick(View v) {
                mNumModel.add(ControllerActivity.this);//通知Model处理数据
            }
        });
    }

    public void updateUI(String text) {//更新UI
        mTextView.setText(text);
    }
}

3. Android中的源码应用

Android中最典型的MVC莫过于ListView了,要显示的数据为Model,而要显示的ListView就是View了,Adapter则充当着Controller的角色。当Model发生改变的时候可以通过调用Adapter的notifyDataSetChanged方法来通知组件数据发生变化,这时Adapter会调用getView方法重新显示内容。具体代码这里就不分析了。

4. MVC的优点

  • 视图层(View)与模型层(Model)解偶,通过Controller来进行联系。
  • 模块职责划分明确。主要划分层M,V,C三个模块,利于代码的维护。

5. MVC的缺点

  • Android中使用了Activity来充当Controller,但实际上一些UI也是由Activity来控制的,比如进度条等。因此部分视图就会跟Controller捆绑在同一个类了。同时,由于Activity的职责过大,Activity类的代码也会迅速膨胀。
  • MVC还有一个重要的缺陷就是View跟Model是有交互的,没有做到完全的分离,这就会产生耦合。

介绍2

MVC(Model-View-Controller)是 Android 早期开发中广泛使用的架构模式,其核心是通过分离数据处理、界面展示和逻辑控制实现代码解耦。以下从核心概念、代码示例、应用场景、优缺点全面解析:

MVC 核心组件与分工

MVC 将应用分为三个核心模块,职责明确:

组件职责Android 对应实现
Model(模型)处理数据逻辑(数据存储、网络请求、业务计算等),不依赖 View 和 controller。Java Bean、数据仓库、数据库工具类
View(视图)展示数据,接收用户交互(点击、输入等),不包含业务逻辑。XML 布局、自定义 View、Activity(部分角色)
Controller(控制器)协调 Model 和 View:接收 View 的用户操作 → 调用 Model 处理数据 → 通知 View 更新。Activity、Fragment(核心角色)

Java 代码示例(用户登录功能)

以一个简单的登录功能为例,展示 MVC 各组件的协作:

1. Model(数据模型与业务逻辑)

负责用户数据的验证和处理(模拟网络请求):

// 数据模型:用户信息
public class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // getter/setter
    public String getUsername() { return username; }
    public String getPassword() { return password; }
}

// 业务逻辑:登录处理(Model 核心)
public class LoginModel {
    // 模拟登录验证(实际可能是网络请求或数据库查询)
    public void login(User user, LoginCallback callback) {
        new Thread(() -> { // 模拟异步操作
            try {
                Thread.sleep(1000); // 模拟网络延迟
                // 简单验证逻辑:用户名密码不为空
                if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) {
                    callback.onSuccess("登录成功");
                } else {
                    callback.onFailure("用户名或密码错误");
                }
            } catch (InterruptedException e) {
                callback.onFailure("网络异常");
            }
        }).start();
    }

    // 回调接口:通知 Controller 处理结果
    public interface LoginCallback {
        void onSuccess(String message);
        void onFailure(String error);
    }
}

2. View(视图:XML 布局 + 交互触发)

负责展示界面和用户交互(点击登录按钮):

<!-- activity_login.xml(View 的布局) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/et_username"
        android:hint="用户名"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/et_password"
        android:hint="密码"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_login"
        android:text="登录"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"/>
</LinearLayout>

3. Controller(控制器:Activity 协调逻辑)

接收 View 的交互,调用 Model 处理数据,再更新 View:

public class LoginActivity extends AppCompatActivity implements LoginModel.LoginCallback {
    // View 引用
    private EditText etUsername;
    private EditText etPassword;
    private TextView tvResult;
    // Model 实例
    private LoginModel loginModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 加载 View
        setContentView(R.layout.activity_login);
        // 初始化 View 和 Model
        initView();
        loginModel = new LoginModel();
    }

    private void initView() {
        etUsername = findViewById(R.id.et_username);
        etPassword = findViewById(R.id.et_password);
        tvResult = findViewById(R.id.tv_result);
        Button btnLogin = findViewById(R.id.btn_login);

        // 接收 View 的用户交互(点击事件)
        btnLogin.setOnClickListener(v -> login());
    }

    // 处理登录逻辑(Controller 核心)
    private void login() {
        String username = etUsername.getText().toString();
        String password = etPassword.getText().toString();
        User user = new User(username, password);
        // 调用 Model 处理数据,传入回调(自身实现)
        loginModel.login(user, this);
        tvResult.setText("登录中...");
    }

    // Model 处理成功后,通知 View 更新
    @Override
    public void onSuccess(String message) {
        runOnUiThread(() -> tvResult.setText(message)); // 切换到主线程更新 UI
    }

    // Model 处理失败后,通知 View 更新
    @Override
    public void onFailure(String error) {
        runOnUiThread(() -> tvResult.setText(error));
    }
}

MVC 的应用场景

  1. 简单应用或原型开发:逻辑简单、页面少的场景(如工具类 App),无需复杂架构即可快速实现。
  2. Android 早期项目:在 Jetpack 组件(如 ViewModel、LiveData)普及前,MVC 是主流架构。
  3. 局部模块:在复杂项目中,部分独立模块(如设置页面、简单表单)可采用 MVC 简化实现。

优点

  1. 结构清晰:分离数据、视图和逻辑,比单一 Activity 中堆砌代码更易维护。
  2. 入门简单:概念直观,适合新手理解架构分层思想。
  3. 视图与数据解耦:Model 不依赖 View,可单独测试(如单元测试验证登录逻辑)。

缺点

  1. Activity 职责过重:Android 中 Activity 既是 Controller 又是 View(负责加载布局、处理生命周期),导致代码臃肿(几百行甚至上千行)。
  2. 耦合度较高:View(XML + Activity)与 Controller(Activity)强耦合,View 变化可能需要修改 Controller 代码。
  3. 可测试性差:Activity 依赖 Android 系统环境,难以进行单元测试(需依赖 instrumentation 测试)。
  4. 不适合复杂项目:随着业务增长,Controller(Activity)会充斥大量逻辑,维护难度急剧上升。

总结

MVC 是 Android 架构的基础,其核心思想(分层解耦)影响了后续的 MVP、MVVM 等模式。但由于 Activity 职责过重、耦合度高等问题,在复杂项目中已逐渐被 MVP(解耦 View 与 Controller)和 MVVM(数据绑定 + ViewModel)替代。不过,理解 MVC 是掌握更高级架构的前提,适合简单场景或新手入门。

资料

MVC、MVP、MVVM,我到底该怎么选?

最近更新:: 2025/10/28 00:02
Contributors: luokaiwen, 罗凯文