常用Android架构设计模式(一)MVC模式

前言#

最近忙于找工作,大家都知道今年移动开发是动荡的一年,在经济危机和创业潮退去的影响下,android和ios必须要面对供大于求的现状。

所以再看了招聘信息之后,发现对于设计模式的要求还是很高的,所以决定写几篇有关于设计模式的文章分享给大家。

第一篇就是最常见的MVC模式。

正文#

MVC应该是一开始接触Java最先听到的模式,尤其是Java的后端开发框架,在xml中配置xxxController,然后通过对应的Controller进行操作,是非常典型的MVC模式。

首先我们来看看MVC的架构图:

常用Android架构设计模式(一)MVC模式_第1张图片
这里写图片描述

图是从其他博客上的盗的,在这里感谢原作者辛苦的画出来。

在看概念之前,我们来分析一下图中的架构:

从图可看出:
Controller是作为一个媒介,处于Model和View之间;
Model和View之间有紧密的联系,耦合性偏强。
Controller不建议直接操作View。
Model不建议直接操作Controller。

ok,下面来看一下概念:

Model: 处理要显示的内容
View: 显示内容
Controller: 格式化model和接收用户的操作事件。

诶,是不是有一种似懂非懂的感觉,那就赶紧实际来写点东西,加深一下理解,首先来看一个未使用mvc模式的简单demo:

public class MainActivity extends AppCompatActivity {

    private TextView textView;


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

        textView = (TextView) findViewById(R.id.textView);
        loading();
    }

    /**
     * 模拟一个loading请求
     */
    private void loading() {
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 模拟得到了数据现在开始处理
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        setLoadStatus(dealResult(LoadStatus.LOAD_SUCCESS));
                    }
                });

            }
        }.start();
    }

    private String dealResult(LoadStatus status) {
        switch (status) {
            case LOADING:
               return "loading...";
            case LOAD_SUCCESS:
                return "load success";
            case LOAD_FAILED:
                return "loading failed";
            default:
                return "";
        }
    }

    private void setLoadStatus(String text) {
        textView.setText(text);
    }

}

代码非常的简单,就是模拟一个加载请求然后根据得到的结果显示一串文字,其中LoadStatus是一个枚举类,里面有三个状态,大家一看就懂,我就不贴出来了。

下面我们来对他进行mvc架构的改造,首先来强化一下的概念,弄清楚我们需要准备的工作:

MainModel:Model层,负责处理MainActivity要显示的数据。
MainView:负责显示MainActivity中的控件和交互操作。
MainActivity:很明显,他就是Controller,负责接收用户的操作事件。

创建完这三个文件,从习惯上肯定要从View层入手,先看看MainView的代码:

/**
 * Created by li.zhipeng on 2017/3/27.
 * 

* MainActivity的View层 */ public class MainView implements View.OnClickListener, MainModel.OnStringCallback{ private MainActivity activity; private OnTextViewClickListener callback; private TextView textView; public MainView(MainActivity activity, OnTextViewClickListener callback) { this.activity = activity; this.callback = callback; initView(); } /** * 初始化 * */ private void initView() { textView = (TextView) activity.findViewById(R.id.textView); textView.setOnClickListener(this); } /** * 设置显示的文字 * */ public void setLoadStatus(String text) { textView.setText(text); } /** * 界面交互,要更新显示的文字 * */ @Override public void onClick(View v) { callback.OnTextViewClickListener((TextView) v); } /** * 销毁释放资源 * */ public void onDestroy(){ this.activity = null; this.callback = null; } @Override public void onResult(LoadStatus status) { setLoadStatus(MainModel.dealResult(status)); } /** * 处理结果的回调函数 */ public interface OnTextViewClickListener { void OnTextViewClickListener(TextView textView); } }

里面已经有各个方法的注释,MainView初始化控件,并设置各种响应事件:例如点击,然后通过回调函数传给MainActivity,然MainActivity来发送具体要操作的指令,实现了MainModel的Callback,等待MainModel把要显示的内容发过来。

然后来看看MainModel:

/**
 * Created by li.zhipeng on 2017/3/27.
 * 

* 负责处理数据的Model层 */ public class MainModel { /** * 加载信息 * */ public static void loadInfo(final OnStringCallback callback) { new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } switch (new Random().nextInt(2)) { case 0: callback.onResult(LOAD_SUCCESS); break; case 1: callback.onResult(LOAD_FAILED); break; case 2: callback.onResult(LOADING); break; } } }.start(); } /** * 处理并显示相应的文字 * */ public static String dealResult(LoadStatus status) { switch (status) { case LOADING: return "loading..."; case LOAD_SUCCESS: return "load success"; case LOAD_FAILED: return"loading failed"; default: return ""; } } /** * 处理结果的回调函数 */ public interface OnStringCallback { void onResult(LoadStatus status); } }

MainModel中有加载信息和处理信息的方法,还有之前MainView实现的Callback。非常简单,没什么可说的,最后就是MainActivity了:

public class MainActivity extends AppCompatActivity implements MainView.OnTextViewClickListener{

    private MainView mainView;

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

        mainView = new MainView(this, this);
        // 向model发送指令,开始得到数据
        MainModel.loadInfo(mainView);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.mainView.onDestroy();
    }

    @Override
    public void OnTextViewClickListener(TextView textView) {
        // 已经得到了数据,对处理进行处理
        MainModel.loadInfo(mainView);
    }
}

MainActivity就是我们的Controller,也就是大哥,负责发送具体的指令,告诉Model:赶紧加载数据给MainView!!

Model乖乖的加载完数据,传给了MainView:我搞定了,你赶紧显示吧...

MainView说你给我这个我也看不懂啊,你再处理处理...

Model再根据LoadStatus,返回给MainView一个字符串:我发给你了啊,你赶紧显示...

MainView说very ok。

第一波流程结束。

然后风骚的用户点击了textView,MainView对MainAcitivity说:大哥,用户点了我咋整?

MainActivity 对 MainModel说:别废话,赶紧再准备一份数据给MainView!!

Model乖乖的加载完数据,传给了MainView:我搞定了,你赶紧显示吧...

MainView说你给我这个我也看不懂啊,你再处理处理...

Model再根据LoadStatus,返回给MainView一个字符串:我发给你了啊,你赶紧显示...

MainView说very ok。

这就是传说中的MVC模式!!!

总结#

让我们最后来分析一下:

从模块结构上看:

1、MainActivity通过雇佣了两个小弟View和Model,把自己包装成大哥Controller,分工明确,大哥Controller除了发号施令,一身轻松。

2、增加了工作量和负担,View和Model的出现,代码量明显要上升了。

从后期维护上看

1、较之前相比,工作划分有了很大的划分,Controller只负责发号施令,剩下的工作交给了View和Model协调解决,后期便于维护查找。

2、Controller把具体的工作甩的干干净净,一旦出现了问题,我们就只能找小弟View和Model解决,并且View和Model耦合性高,私底下有一些不可描述PY交易,一旦出现问题,他俩可能要互相甩锅。

架构图上不建议Controller直接操作View,但是这个有时候不好说,例如如果是点击了textView,隐藏或显示另一个控件,那就直接操作mainView就可以了。当然你也可以在MainView中自己去隐藏和显示,但是这就更加违背了MVC一开始的设计规则,也不能把显示控件划分到Model中。这三者难免要进行取舍,这也体现了MVC在这一方面的设计的缺点。

MVC适合什么样的项目呢?个人觉得不适合小型项目,毕竟功能模块的分离还是很复杂的,需要耗费时间去设计,如果是交接的话,一个界面要看三个文件还是挺费劲的,但是每个人的侧重点不一样,大家自己考虑之后再做定夺。

到此为止,MVC模式就介绍完了,我们已经对MVC有了深入的了解,但是还需要多多练习,仔细体会MVC的优劣,demo仅供参考,如果你有更好的MVC模块划分和更好的理解,欢迎留言大家一起进步。

下一篇我们来谈一谈 MVP模式。

源码下载链接

你可能感兴趣的:(常用Android架构设计模式(一)MVC模式)