浅析MVC、MVP、MVVM 框架实现

复杂的软件必须有清晰合理的架构,否则无法开发和维护。为了将业务和视图的实现代码分离,目前比较流行三种前端架构:

  • MVC ( Model-View-Controller)
  • MVP (Model-View-Presenter)
  • MVVM( Model-View-ViewModel)

Model 为模型层,主要管理业务模型的数据和行为;View 为展示层,其职责就是管理用户界面。

三个架构模式目的都是为了解耦 Model 和 View,主要不同点就在于三者实现解耦的方案不同。

1、MVC

一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。 简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示,当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。 如下图:

代码实现如下:

's voice is .var M = {    voices : {        chick : 'bi bi',        hen : 'gu gu',        cock : 'wo wo'    },    name : '',    voice : '',    change : function(name){        this.name = name;        this.voice = this.voices[name];        V.update();//调用V    },    get : function(k){        return this[k];    }}; var V = {    init : function(){        document.querySelector('#animal').onchange= function(){            C.set(this.value);//调用C        };    },    update : function(){        document.querySelector('#name').textContent = M.get('name');        document.querySelector('#voice').textContent = M.get('voice');    }}; var C = {    init : function(){        V.init();    },    set : function(name){        M.change(name);//调用M    }}; C.init();

以上代码很清晰分出M、V和C三个模块,V通过事件通知C控制M的变化,M变化后会调用V进行视图更新,整个流程是单向的。

2、MVP

MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

各部分之间的通信,都是双向的。;View 与 Model 不发生联系,都通过 Presenter 传递;View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。如下图:

代码实现如下:

'voice is .var M = {    voices : {        chick : 'bi bi',        hen : 'gu gu',        cock : 'wo wo'    },    name : '',    voice : '',    change : function(name){        this.name = name;        this.voice = this.voices[name];    },    get : function(k){        return this[k];    }}; var V = {    init : function(){        document.querySelector('#animal').onchange = function(){            C.set(this.value);//调用C        };    },    update : function(kv){        for(k in kv){            document.querySelector('#'+k).textContent = kv[k];        }    }}; var P = {    init : function(){        V.init();//调用V    },    set : function(name){        M.change(name);//调用M        V.update({            name : M.get('name'),             voice : M.get('voice')        });//调用V    }}; P.init();

代码来看跟MVC差不太多,区别主要在于M和V没有直接交互,而是通过P来进行完全控制,所以P也被称为控制狂,任何交互上的事情都由很强的控制欲。

3、MVVM

MVVM采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。AngularJS 和 Vue 都采用这种模式,而React采用了单向数据流,属于MVP架构。  

要实现数据绑定,通常都采用发布者-订阅者模式进行实现,但这部分工作如果由开发人员自己来写代码实现,其实还是挺复杂的,因此,各大平台都提供了各自的内部实现。比如 Vue 和 AngularJS 自身都实现了数据绑定,Android 目前最主流的方案就是采用 Jetpack,iOS 最常用的方案则是结合 ReactiveCocoa(RAC)实现。

MVP 和 MVVM 都是为了解决界面和数据的分离问题,两者只是采用了不同的实现方案。MVP 之间的交互主要是通过接口实现的,其主要弊端就是需要编写大量接口。而 MVVM 则是通过数据绑定的方式实现交互,虽然其实现需要依赖具体的一些框架工具,但明显大大减少了开发者需要编写的代码量。

代码实现如下:

         'voice is .var M = {    voices : {        chick : 'bi bi',        hen : 'gu gu',        cock : 'wo wo',    },    name : '',    voice : ''    doChang : function(){        M.name = this.value;        M.voice = this.voices[obj.name];    }}; var V = {       bindEvent : function(el, evt, func){        el['on'+evt] = M[func]();    },    updateText : function(el, text){        el.textContent = text;    }}; var VM = {    init : function(rootSelector){        this.observer();        this.compiler(rootSelector);    },    paths : {},    observer : function(){        var _this = this;        for(var k in M){            (function(k){                var name = k, value = M[k];                Object.defineProperty(M, name, {                    get : function(){                        return value;                    },                    set : function(v){                        value = v;                        V.updateText(_this.paths[name], v);                    }                });            })(k);        }            },    compiler : function(rootSelector){        var binds = document.querySelector(rootSelector).querySelectorAll('[data-bind]');        for(var i=0, len=binds.length;i-1){//事件指令                var directives = directive.split(':');                var evt = directives[0], func = directives[1];                V.bindEvent(el, evt, func);            }else{//文本指令                this.paths[directive] = el;                V.updateText(el, M[directive]);            }        }    }}; VM.init('#content');

MVC/MVP/MVVM的原理以及代码实现,文章到这里就差不多结束了。可能文章解析的不够全面,需更全面对架构的进阶。我们可以前往这里获取学习笔记方式,里面有对(架构的全方位解析+大厂架构实战演练),展示如下部分截图:《Android架构学习》私信:“手册”获取!


【私信“手册”获取】架构设计必备核心技术手册

小结

从 MVC 架构模式到 MVVM,从分离展示层到展示模型层,经过几十年的发展和演变,MVC 架构模式出现了各种各样的变种,并在不同的平台上有着自己的实现。

MVC/MVP/MVVM都是根据不同的应用需求和应用环境逐步发展而来的,它们都有各自优缺点和适用环境。比如Web开发中因为要跨越网络通讯,如果使用MVP或者MVVM来实现代价是巨大的,因为目前来说网络数据很珍贵的资源。

框架   MVC   MVP
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章