MVC设计详解

该总来,说了要写的就一定会写,就是这么信守承诺,就是这么勤快,就喜欢说废话加长博文长度。

MVC模式是我接触的第一种框架,这一框架对项目分块的很清晰。将项目分解为Model-View-Controller,对于一个Android项目来说,这样的模块划分方式还是比较方便开发的(至少我用在当时的项目确实还行)。请注意,MVC并不是一种设计模式,之前的标题有所误导,现在已经修改。
将代表显示的部分划分至View,将代表数据实体的部分划分至Model,将代表数据处理的部分划分至Controller,这样划分之后整个项目的结构也就清晰了很多。

首先,我希望能分别介绍一下MVC的三部分内容各自的属性和特点,这样应该能够更好的整体理解MVC这一框架。

Model

Model部分,也就是模型部分,这一部分将需要在View中显示的数据整合为一个实体,可以视为View显示内容的实体对象
举个简单的例子:
一个TextView中需要显示一个人的姓名和年龄,那么对应这一个View需要的数据,可以定义一个Person类,其中包含name和age属性。

//一个简单的Model,定义了View中显示内容模型
class Person{
    private String name;
    private int age;

    /***********/
    geter...
    setter...
    /***********/
}

Model中定义的属性部分是由View的现实需要决定的,当然也并不是绝对,Model中的属性更多根据获取的数据来进行定义

同样举个例子:
依照获取的数据,一个人拥有基本的属性为姓名、年龄、性别、身高、体重。那么定义一个Model可以将所有数据包含的属性都进行整合。在不同的View进行显示时都能够使用这一Model。

//包含了所有数据内容的Model,能够适用于多个View
class Person{
    private String name;
    private int age;
    private String gender;
    private int height;
    private int weight;

    /**********/
    getter
    setter
    /**********/
}

从上面的例子可以看的出来,事实上Model部分就是数据实例定义,将各个类型的数据规整为不同的类,划分至Model中,通过这些类来进行与View之间的交互,同时通过这些类获取并保存数据。

View

view部分内容,通常称为视图部分,这一部分内容主要是用于做显示功能的,Android应用作为移动客户端上的产品,相比于数据处理,更多的是对View的开发。可以简单的将View看做视图内容,在Android方面来说,基本是xml文件的定义。
事实上Android中因为自定义控件的存在,出现了各种不同功能不同形式的View,当然本质上还是相差不远的,大部分的目的都是——显示数据,与数据交互

举个简单的例子:

//Android中的基础控件(TextView、Button)

//常用于显示数据
<TextView
    android:id="@+id/tv_mvc"
    android:width="warp_content"
    android:height="warp_content"
    text="hello mvc"/>

//常用于点击交互
<Button
    android:id="@+id/bt_mvc"
    android:width="warp_content"
    android:height="warp_content"
    text="getName"/>

以上例子省略的外部的layout,这是一个简单的View组合,包含TextView和Button两个View组件,以上的部分可以完成简单的数据显示,并且能够相应用户操作,这也就是View的主要作用。

Controller

这是View与Model之间进行交互的桥梁,而Controller的作用就是通过对View动作的响应来操作Model,在Android端来说,这些工作不可避免的要在Activity或是Fragment中来完成。这也就是之前提到的使用MVC会导致Activity/Fragment变得臃肿的主要原因。

举个例子:

"/**结合之前View和Model中的例子来看**/"

"//创建Person对象实例"
Person person = new Person();

"//Button点击监听"
bt_mvc.setOnClickListener(new OnClickListener(){
    public void onClick(View v){
        "//获取TextView显示的文本"
        String name = tv_mvc.getText().toString();
        "//存储person对象的name属性"
        person.setName(name);
    }
});

这是一次简单的Controller操作过程,监听View(Button)的点击事件,当Button受到用户点击时,获取View(TextView)的文本内容,将文本内容的String值赋给Model(Person)实例。通过Controller完成由View响应开始完成与Model交互的过程。

MVC框架分解

完成了MVC框架的各个部分之后,我们可以从将框架稍稍分解来观察不同部分之间是怎样进行交互的。

  • M——V
    之前介绍过,Model部分与View部分是可以直接进行交互的,比较常见的交互有Adapter的形式,修改Model,通过BaseAdapter的notifyDataSetChanged()刷新View。这个类型的交互应该不难理解。

  • M——Controller/V——Controller
    直接的修改,不做太多解释了。

  • V——Controller
    这一部分内容常见的有控件的回调方法,通过对控件各个事件监听来完成对成View与Controller之间的交互。

框架依照这个形式搭建,将项目中的内容按照这三部分进行划分。首先项目的结构就能够比较清晰的呈现;其次在维护是也能够较快捷的找到所需要维护位置及相应的类。Android端也更便于修改项目之间的逻辑。但依照这一框架搭建项目时,非常直观的问题:Activity、Fragment中的代码量极大。View与Model之间的交互基本都会在Activity中进行,还有Controller也很难避开Activity。

MVC整体示例

Model

/*Person类,包含属性:姓名,性别,年龄,身高,体重*/
public class Person {

    private String name;
    private String gender;
    private int age;
    private int height;
    private int weight;

    public Person(String name, String gender, int age, int height, int weight) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.height = height;
        this.weight = weight;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

View

Activity的布局文件

<?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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_example"
            android:layout_width="0dp"
            android:gravity="center_horizontal"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="name"
            android:textSize="18sp"/>

        <Button
            android:id="@+id/bt_example"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="get"/>
    </LinearLayout>

    <ListView
        android:id="@+id/lv_example"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

数据列表布局文件

<?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_lv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        android:textSize="18sp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_lv_age"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="age"
            android:textSize="18sp"/>

        <TextView
            android:id="@+id/tv_lv_gender"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="gender"
            android:textSize="18sp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_lv_weight"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="weight"
            android:textSize="18sp"/>

        <TextView
            android:id="@+id/tv_lv_height"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="height"
            android:textSize="18sp"/>
    </LinearLayout>
</LinearLayout>

Controller

Button bt_example = (Button) findViewById(R.id.bt_example);
assert bt_example != null;
bt_example.setOnClickListener(this);

//通过用户点击,获取整体Person数据
public void onClick(View v) {
    //获取EditText中输入文本
    String name = et_example.getText().toString();
    if (TextUtils.isEmpty(name)) {
        return;
    }

    list.clear();
    if (name.equals(person.getName())) {
        list.add(person);
        adapter.notifyDataSetChanged();
    }
}

View与Model交互

以Adapter中的getView为例,Model与View之间能够直接进行交互,ListView中显示的控件都通过ViewHolder做了处理。关于ViewHolder就不做赘述了。

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = View.inflate(ExampleActivity.this, R.layout.layout_lv_example, null);
    }

    ViewHolder holder = ViewHolder.getInstance(convertView);

    Person person = list.get(position);

    holder.tv_lv_name.setText("name:" + person.getName());
    holder.tv_lv_age.setText("age:" + String.valueOf(person.getAge()));
    holder.tv_lv_gender.setText("gender:" + person.getGender());
    holder.tv_lv_height.setText("height:" + String.valueOf(person.getHeight()));
    holder.tv_lv_weight.setText("weight:" + String.valueOf(person.getWeight()));

    return convertView;
}

至此,以上就是MVC的整体,事实上这一次总结对我帮助也很大,mvc设计模式的各个部分更加清晰。但是框架来说,最好还是经过使用才能最好的掌握。


总结

框架到底该怎样选择,这个实在还是该看实际情况。网络上搜索MVC经常看到”MVC已经落伍。。。”之类的帖子,但是事实上MVC在部分项目框架中依然好用,不必对其他新出现的框架迷信,适合项目的框架才是应该选用的框架

那么,关于之前说的月底前写完MVC、MVP、MVVM的介绍,其实我说的是8月底,毕竟,我可是咸鱼啊。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值