zoukankan      html  css  js  c++  java
  • MVC架构模式

     MVC 架构设计

    MVC的思想很简单,就是“分层”。

    以前写代码,都是所有的代码放在一起。功能实现了,但是显得很臃肿,不方便维护。

    MVC的分层:分成三层。

    M:Model 模型层 负责存储和提供数据

    V:View 视图层 负责渲染页面

    C:Controller 控制器层 负责实现逻辑交互

    MVC的功能:

    C是核心,可以从M中获取数据、更新数据 可以更新视图

    V可以从M中获取数据 M只负责存储和提供数据



     

    实现MVC:

     

    define('MVC', [], function() {
        // 定义MVC,来包装这个模块
        let MVC = (function() {
            // MVC分成三个部分:M, C, V
            let M = (function() {
                // 闭包中,存储模型数据
                let _model = {};
                // 返回值就是暴露的接口
                return {
                    // 写数据
                    set(key, value) {
                        // 对属性名做处理
                        let arr = key.split('.');   // ['b', 'c', 'd', 'e']
                        // 取出最后一个属性
                        let saveKey = arr.pop();    // arr = ['b', 'c', 'd']
                        // 定义result存储每次判断的结果
                        let result = _model;
                        // 逐一遍历,存储数据
                        arr.forEach(item => {
                            // 判断item属性是否存在
                            if (result[item] === undefined) {
                                // 属性不存在,设置默认值
                                result[item] = {};
                            }
                            // 只有对象以及函数可以添加属性
                            if (result[item] !== null && (typeof result[item] === 'object' || typeof result[item] === 'function')) {
                                // 让result存储当前的结果
                                result = result[item]
                            } else {
                                // result[item]是值类型的,不能添加属性
                                throw new Error('属性' + item + '的数据类型是' + typeof result[item] + ',该类型不能添加属性')
                            }
                        })
                        // 存储数据
                        result[saveKey] = value;
                        // console.log(_model);
                    },
                    // 读数据
                    get(key) {
                        // 对属性名切割
                        let arr = key.split('.');   // ['b', 'c', 'd', 'e']
                        // 定义结果
                        let result = _model;
                        // 从左到右遍历每一个属性
                        arr.some(item => {
                            // 如果是undefined就没有必要再去遍历了
                            // 数组遍历可以中断的方法:some, every, find, findIndex
                            result = result[item];
                            // result是否为undefined
                            return result === undefined;
                        })
                        // 返回数据
                        return result;
                    }
                }
            })();
            // 存储数据
            // M.set('a', [1, 2, 3])
            // // M.set('b.c', 100)
            // M.set('b.c.d.e', [1, 2, 3])
            // console.log(M.get('b.c.d.e'));
            // console.log(M.get('b.c'));
            // V
            let V = (function() {
                // 定义存储视图的容器
                let _view = {}
                // 返回值就是暴露的接口
                return {
                    // 添加视图
                    add(name, fn) {
                        // 直接存储
                        _view[name] = fn;
                    },
                    // 渲染试图
                    render(name) {
                        // 找到该方法,将其执行, 可以将模型传递进来
                        return _view[name] && _view[name](M)
                    }
                }
            })()
            // C
            let C = (function() {
                // 控制器
                let _ctrl = {};
                // 返回值就是暴露的接口
                return {
                    // 存储控制器
                    add(name, fn) {
                        // 直接存储
                        _ctrl[name] = fn;
                    },
                    // 初始化控制器
                    init(name) {
                        // 将对应的控制器执行
                        _ctrl[name] && _ctrl[name](V, M)
                    },
                    // 执行所有的控制器
                    initAll() {
                        // 遍历控制器
                        for (let name in _ctrl) {
                            // 执行
                            this.init(name)
                        }
                    }
                }
            })()
            // 定义观察者模式
            let Observer = (function() {
                // 消息系统
                let _msg = {};
                // 暴露接口
                return {
                    // 订阅消息
                    on(type, fn) {
                        // 判断消息是否存在
                        if (_msg[type]) {
                            // 直接存储
                            _msg[type].push(fn);
                        } else {
                            // 新建消息管道
                            _msg[type] = [fn];
                        }
                    },
                    // 发布消息
                    trigger(type, ...args) {
                        // 如果存在消息,遍历消息管道,执行回调函数
                        _msg[type] && _msg[type].forEach(fn => fn(...args))
                    },
                    // 注销消息
                    off(type, fn) {
                        // 有消息回调函数,删除
                        if (fn) {
                            // 如果消息管道存在,并且有该回调函数, 将其删除
                            // >= <= > < === ==   << >> >>>
                            _msg[type] && _msg[type].indexOf(fn) >= 0 && _msg[type].splice(_msg[type].indexOf(fn), 1)
                        } else if (type) {
                            // 清空该消息管道
                            _msg[type] = [];
                        }
                    }
                }
            })()
            // 暴露接口
            return {
                // 添加模型
                addModel(key, value) {
                    // 存储模型
                    M.set(key, value)
                },
                // 添加视图
                addView(name, fn) {
                    // 存储视图
                    V.add(name, fn);
                },
                // 添加控制器
                addCtrl(name, fn) {
                    // 存储控制器
                    C.add(name, fn)
                },
                // 启动应用程序
                install() {
                    // 逐一执行所有的控制器
                    C.initAll();
                },
                // 暴露整体
                Observer,
                // 将接口复制过来。
                ...Observer
            }
        })();
        // 暴露接口
        return MVC;
    })

     

     

     

     

     

  • 相关阅读:
    How to use my view helpers in my ActionMailer views?
    大败笔,状态机
    把程序进行上线部署调试了,
    支付接口心得
    rails3 正则路由
    linux下配置Mysql远程访问,不受ip限制
    ActionController::InvalidAuthenticityToken解决办法
    支付宝接口错误
    DHTML 中的绝对定位
    部署备份
  • 原文地址:https://www.cnblogs.com/yess/p/13610793.html
Copyright © 2011-2022 走看看