• 从Android开发看MVC


    MVC(Model View Controller),是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

    MVC 模式提供了对 HTML、CSS 和 JavaScript 的完全控制。Model(模型)表示应用程序核心(比如数据库记录列表),是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据;View(视图)显示数据(数据库记录),是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的;Controller(控制器)处理输入(写入数据库记录),是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。三者之间的运作流程如下:

     

     

    View接受用户的交互请求,View将接收到的用户的请求转交给Controller;Controller操作Model来进行数据更新过程,数据更新之后,Model通知View数据的变化,View来向用户展示更新之后的数据。

    在学习MVC软件架构模式以及移动应用开发这两种知识体系时,我发现,Android开发所使用的架构,也可以说是MVC架构,Android开发主要是采用XML文件进行界面的开发,而MVC模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。所以,此时的View层是这些XML文件,用于界面显示与用户交互,使用的时候可以非常方便的引入,同时便于后期界面的修改,逻辑中与界面对应的id不变化则代码不用修改,大大增强了代码的可维护性。Android的控制层相当于众多的Activity。Activity是一个Android的应用组件,它提供屏幕进行交互。每个Activity都会获得一个用于绘制其用户界面的窗口,窗口可以充满哦屏幕也可以小于屏幕并浮动在其他窗口之上。一个应用通常是由多个彼此松散联系的Activity组成,一般会指定应用中的某个Activity为主活动,也就是说首次启动应用时给用户呈现的Activity。这句话也就暗含了不要在Activity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Actiivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。针对业务模型,建立的数据结构和相关的类,就可以理解为App的Model,Model是与View无关,而与业务相关的。对数据库的操作、对网络等的操作都应该在Model里面处理,对业务计算等操作也是必须放在的该层的。

    下面使用一个登录实例来进行MVC模式的展示:

    //定义Model实现
    package yuekaoti.mvcdemo.model;
    import yuekaoti.mvcdemo.custominterface.LoginListener;
    import yuekaoti.mvcdemo.model.baseModel.IUser;
    public class UserModel implements IUser {
        public void login(String userPhone, String userPass, LoginListener listener) {
            if (TextUtils.isEmpty(userPhone)) {
                listener.fail("手机号不能为空");
            } else {
                if (TextUtils.isEmpty(userPass)) {
                    listener.fail("密码不能为空不能为空");
                } else {
                    int code = postLogin(userPhone, userPass);
                    if (code == 200) {
                        listener.success("登录成功");
                    } 
           else {
                        listener.fail("登录失败,请稍候重试");
                    }
                } 
        }
            private int postLogin(String userPhone, String userPass) {
            return 0;
        }
    }
    
    //定义Controller
    import android.annotation.SuppressLint;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import yuekaoti.mvcdemo.R;
    import yuekaoti.mvcdemo.custominterface.LoginListener;
    import yuekaoti.mvcdemo.model.UserModel;
    public class MainActivityFragment extends Fragment implements View.OnClickListener {
        private View view;
        private EditText etPhone, etPass;
        private TextView tvResult;
        //Model
        private UserModel userModel;
        public MainActivityFragment() {
        }
    
         public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.fragment_main, container, false);
            return view;
        }
            public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            //创建model User对象
            userModel = new UserModel();
            //初始化控件
            etPhone = view.findViewById(R.id.etPhone);
            etPass = view.findViewById(R.id.etPass);
            Button btnLogin = view.findViewById(R.id.btnLogin);
            btnLogin.setOnClickListener(this);
            tvResult = view.findViewById(R.id.tvResult);
        }
           public void onClick(View v) {
            switch (v.getId()) {
                //登录 view
                case R.id.btnLogin:
                    String phone = etPhone.getText().toString().trim();
                    String pass = etPass.getText().toString().trim();
                    userModel.login(phone, pass, new LoginListener() {
                    public void success(String result) {
                            updateResult(result);
                     public void fail(String errorMsg) {
                            updateResult(errorMsg); }
                    });
                    break;
                default:
                    break;
            }
        }
        
        @SuppressLint("SetTextI18n")
        private void updateResult(String msg) {
            tvResult.setText(getString(R.string.text_login_result) + ":" + msg);
        }
    }

    从代码中可以看出,Activity持有了UserModel模型的对象,当用户有点击Button交互的时候,Activity作为Controller控制层读取View视图层EditText View的数据,然后向Model模型发起数据请求,也就是调用UserModel对象的方法 login()方法。当Model模型处理数据结束后,通过接口LoginListener通知View视图层数据处理完毕,然后View视图层调用updateResult方法更新UI。至此,整个MVC框架流程就在Activity中完成。

    在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户 界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。Activity中的View关心业务和数据,才能知道自己该怎么展示(比如成功显示绿色,失败显示红色)。很难在不沟通的情况下一个负责获取数据,一个负责展示UI,完成这个功能!并且逻辑都在Activity里面,View和Controller根本没有分开,并且数据和View严重耦合。

    参考文献:

    [1]百度百科:MVC模式

    https://baike.baidu.com/item/MVC%E6%A1%86%E6%9E%B6/9241230?fromtitle=MVC%E6%A8%A1%E5%BC%8F&fromid=713147&fr=aladdin

    [2] Android Activity详解

    https://blog.csdn.net/fjnu_se/article/details/80703815

    [3]MVC模式与实例讲解

    https://www.pianshen.com/article/9978305887/

  • 相关阅读:
    MVC5 Entity Framework学习之Entity Framework高级功能(转)
    js获取当前日期的前一天、一月、一年的日期 明天、后天(转)
    easyui datagrid 分页
    博客园技术精粹集合留贴
    常用C# DateTime 日期计算
    Jquery设置Cookie
    设计模式 -- 装饰者模式
    设计模式 -- 策略模式
    IBatis.Net中调用存储过程
    其他元素条件 IBatisNet
  • 原文地址:https://www.cnblogs.com/Qi77/p/13097807.html
Copyright © 2020-2023  润新知