JS常用设计模式(MVC、MVP、MVVM及其他设计模式)

MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式。不同于设计模式(Design Pattern),只是为了解决一类问题而总结出的抽象方法,一种架构模式往往使用了多种设计模式。要了解MVC、MVP和MVVM,就要知道它们的相同点和不同点。不同部分是C(Controller)、P(Presenter)、VM(View-Model),而相同的部分则是MV(Model-View)。

一、MVC

MVC模式的意思是,软件可以分成三个部分。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第1张图片

视图(View):用户界面。

控制器(Controller):业务逻辑

模型(Model):数据保存

各部分之间的通信方式如下。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第2张图片

View 传送指令到 Controller

Controller 完成业务逻辑后,要求 Model 改变状态

Model 将新的数据发送到 View,用户得到反馈

所有通信都是单向的。

二、互动模式

接受用户指令时,MVC 可以分成两种方式。一种是通过 View 接受指令,传递给 Controller。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第3张图片

另一种是直接通过controller接受指令。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第4张图片

三、实例:Backbone

实际项目往往采用更灵活的方式,以Backbone.js为例。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第5张图片

1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。

2. 用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View。

3. Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。所以,Backbone 索性取消了 Controller,只保留一个 Router(路由器) 。

四、MVP

MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第6张图片

1. 各部分之间的通信,都是双向的。

2. View 与 Model 不发生联系,都通过 Presenter 传递。

3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

五、MVVM

MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。

JS常用设计模式(MVC、MVP、MVVM及其他设计模式)_第7张图片

唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Angular和Ember都采用这种模式。

1、js工厂模式

1 var  lev=function(){

2    return"嘿哈"; 

3 };

4  function Parent(){

5     var Child =new object();

6     Child.name = "李小龙";

7     Child.age = "30";

8     Child.lev = lev;

9      return Child;

10

11   };

12   var   x=Parent();

13 alert(x.name);

14  alert(x.lev());

说明:

在函数中定义对象,并定义对象的各种属性,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法。

引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new object(); 因为后者可能会出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象。

在函数的最后返回该对象。

不推荐使用这种方式创建对象,但应该了解。  

2、js构造函数模式

1 var  lev=function(){

2  return"嘿哈"; 

3 };

4  function Parent(){

5    this.name = "李小龙";

6     this.age = "30";

7      this.lev = lev;     

8   };

9  var x=Parent();

10  alert(x.name);

11  alert(x.lev());


说明:

与工厂方式相比,使用构造函数方式创建对象无需在函数内部创建对象,而使用this指代,并而函数无需明确return。

同工厂模式一样,虽然属性的值可以为方法,仍建议将该方法定义在函数之外。

同样的,不推荐使用这种方式创建对象,但仍需了解。

3、js原型模式

1 var lev=function(){

2 return"嘿哈"; 

3 };

4  function Parent(){

5   Parent.prototype.name = "李小龙";

6   Parent.prototype.age = "30";

7    Parent.prototype.lev = lev;     

8  };

9  var  x=Parent();

10  alert(x.name);

11  alert(x.lev());

说明:

函数中不对属性进行定义。

利用prototype属性对属性进行定义。

同样的额,不推荐使用这样的方式创建对象。

4、构造函数+原型的js混合模式(推荐)

1  function Parent(){

2    this.name = "李小龙";

3    this.age = "30";     

4  };

5   Parent.prototype.lev=function(){

6       returnthis.name;

7    }

8  var x=Parent();

9 alert(x.name);

10  alert(x.lev());

说明:

该模式是指混合搭配使用构造函数和原型方式。

将所有的属性,不是方法的定义在函数中(构造函数的方式),将所有属性值为方法的利用prototype在函数之外定义(原型方式)。

推荐使用这样的方式创建对象,这样有好处。

5、构造函数+原型的动态原型模式(推荐)

1 function Parent(){

2  this.name = "李小龙";

3  this.age = "30"; 

4   if(typeofParent.lev == "undefined"){

5        Parent.prototype.lev =function(){

6               returnthis.name;

7        }

8        Parent.lev =true;

9    }   

10 };

11

12    varx=Parent();

13     alert(x.lev());

说明:

动态原型方式可以理解为混合构造函数,原型方式的一个特例。

该模式中,属性为方法的属性直接在函数中进行了定义,但是因为

if(typeof Parent.lev == "undefined"){

          Parent.prototype.lev = function(){

            return this.name;

          }

   Parent.lev = true;

    } 

从而保证创建该对象的实例时,属性的方法不会被重复的创建。

你可能感兴趣的:(JS常用设计模式(MVC、MVP、MVVM及其他设计模式))