软件架构模式、软件设计模式傻傻分不清楚?mvc,mvp,mvvm 有什么区别,各自都有什么优缺点和适用的场景?前端常用的设计模式都有哪些?今天主要从前端开发的角度来聊一聊软件设计模式,也希望看完这一篇文章能对你有所帮助。
软件架构模式的种类
在做软件架构设计时,根据不同的抽象层次可分为三种不同层次的模式:架构模式(Architectural Pattern)、设计模式(Design Pattern)、代码模式(Coding Pattern)。
- 架构模式是一个系统的,多层次策略,涉及到大尺度的组件以及整体性质和力学。它描述软件系统里的基本结构组织或纲要,提供一些事先定义好的子系统,指定它们的责任,并给出把它们组织在一起的法则和指南。架构模式的好坏可以影响到总体布局和框架性结构。
- 设计模式是中等尺度的结构策略。它描述了普遍存在的相互通讯组件中重复出现的结构。这些中等尺度的结构实现了一些大尺度组件的行为和它们之间的关系。设计模式定义出子系统或组件的微观结构。 模式的好坏不会影响到系统的总体布局和总体框架。
- 代码模式(或成例)是与特定的范例和特定语言有关的编程技巧,它描述怎样利用一个特定的编程语言的特点来实现一个组件的某些特定的方面或关系。代码模式的好坏会影响到一个中等尺度组件的内部、 外部的结构或行为的底层细节,但不会影响到一个部件或子系统的中等尺度的结构,更不会影响到系统的总体布局和大尺度框架。
从架构模式谈起
没有进行架构设计的应用程序通常是紧耦合的,糟糕的代码耦合让整个系统变得难以理解、难以修改、难以分工、难以集成。针对代码耦合的问题,软件界进行了大量的理论研究和实践,最后发现:系统的架构设计,是改善耦合的最好方式。 软件工程师们在多年的架构设计工作中总结出一些经验,这些经验被称为“架构模式”。架构模式可以帮助你定义程序的基本特征和行为。例如一些架构模式让程序成为大规模(scalable)的程序,而有些模式让程序变得灵巧敏捷(agile)。知道这些架构的特征,优点和缺点,你就可以根据你特定的业务需求和目标从容的选择一种架构模式。
常见的架构模式有:分层模式,微核模式,管道与过滤器,MVC模式,REST模式,SOA模式
模式 | 描述 | 优势 | 劣势 |
---|---|---|---|
分层架构 | 最常见的架构模式,SSH(Structs, Spring, Hibernate)简直就是事实标准. 分层架构通常划分为:展现层,业务逻辑层,持久层,数据库层,有时也将业务逻辑层和持久层合二为一 | 分层架构最大的优势是每层可以只关注一种需求.相对早期的架构,这样的模式更清晰可维护,可测试性高 | 灵活性低,扩展性差,不易于部署 |
微核架构 | 又称为"插件架构"(plug-in architecture),指的是软件的内核相对较小,主要功能和业务逻辑都通过插件实现,插件则是互相独立的 | 良好的功能延展性,插件间相互隔离,易于部署,可定制性高,渐进式开发 | 扩展性差,开发难度较高 |
事件驱动架构 | 通过事件(状态发生变化时,软件发出的通通知)进行通信的软件架构一般分为:事件队列,分发器,事件通道,事件处理器 | 分布式的异步架构,事件处理器之间高度解耦,软件的扩展性好,适用性广性能较好,容易部署 | 分布式和异步特性导致架构较难测试,开发相对复杂 |
微服务架构 | 服务导向架构(service-oriented architecture,缩写 SOA)的升级。每个服务就是独立的部署单元(separately deployed unit)。单元都是分布式的,互相解耦,通过远程通信协议(比如REST、SOAP)联系。实现模式:RESTful API模式,RESTful 应用模式,集中消息模式 | 扩展性好,易容易部署,易于开发和测试 | 由于依赖大量微服务,导致系统凌乱和笨重且性能不佳,服务间通信复杂 |
云架构 | 主要解决扩展性和并发的问题,把数据复制到内存中,变成可复制的 内存数据单元.主要分为两部分,处理单元,虚拟中间件 | 高负载,高扩展性,动态部署 | 实现复杂,不适合大量数据吞吐的大型数据库应用,较难测试 |
以上.
简单了解这些基本的架构模式之后,来重点看下前端开发中常用的架构模式吧.
MVC模式
MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC模式最早由Trygve Reenskaug 在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构(Smalltalk-80).此后,MVC模式不断发展,并在此基础上衍生出其他变种,例如: MVP, MVVM.
MVC模型本身并非是只有一种标准方案,而是存在多种不同的描述的。但是有一个共同点,就是他们都把整个应用分成Model, View,和 Controller三个部分.
维基百科中,对这三部分的描述如下:
模型(Model) - 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。 “Model”有对数据直接访问的权力。 “Model”不依赖“View”和“Controller”,也就是说,Model不关心它会被如何显示或是如何被操作。但是 Model 中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此 Model 的 View 必须事先在此 Model 上注册,从而,View 可以了解在数据 Model 上发生的改变。(比如:观察者模式(软件设计模式)) 视图(View) - 能够实现数据有目的的显示,通常是一个用户界面元素。在View中一般没有程序上的逻辑。为了实现 View 上的刷新功能,View 需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。 控制器(Controller) - 起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。
调用关系
由于实现方式不同,所以各种方式的 M
,V
, C
三类的调用关系也不尽相同.这里以观察者模式实现的角度来说一下三者的调用关系:
当用户对View操作,View捕获到这个操作后,会转发给Controller处理,Controller会根据这个操作来决定调用Model的哪个接口,然后由Model执行相关的业务逻辑;View会在Model中注册相关的事件,当Model更新之后,会通知View;view收到通知后,会再次向Model请求最新的数据,然后重新渲染界面.
一般来说,为了避免直接的耦合关系,都会使用观察者模式。有些做法下,Model会和对应的View“同步绑定”,他们的刷新事件,也是通过观察者模式的Update事件来通知的。
需要强调一点的是,MVC中所有通信都是单向的。
这里有一个通过 JavaScript 所实现的基于 MVC 模型,需要注意的是:MVC 不是一种技术,而是一种理念。 ```js /** 模拟 Model, View, Controller */ var M = {}, V = {}, C = {};
/** Model 负责存放资料 */ M.data = "hello world";
/** View 负责将资料输出到屏幕上 */ V.render = (M) => { alert(M.data); }
/** Controller 作为一个 M 和 V 的桥梁 */ C.handleOnload = () => { V.render(M); }
/** 在网页读取的时候呼叫 Controller */ window.onload = C.handleOnload; ``` 在这个简短的代码中就具有一个完整的 MVC 模式。
优缺点
优点: 1. 基于关注点分离的思想,业务逻辑和表示层分离,同一个 Model 可以被不同的 View 重用,所以大大提高了代码的可重用性。 2. 便于做单元测试和自动化测试;(前后端分离)
缺点: 1. View和Model不完全脱离,存在一些逻辑耦合,所以View无法组件化.
MVP
Model-view-presenter,简称MVP,是针对MVC模式的一些问题,改良之后演变而来的一种用户界面设计模式.
MVP模式有两种: 1. Passive View 2. Supervising Controller
(今天主要讨论Passive View模式)
调用关系
其实,理解了MVC模式之后,再来看MVP模式,就会相对容易理解一些了.
和 MVC 模式一样, 用户操作view后,View会将用户操作转发给Presenter. Presenter会执行相关的应用程序逻辑,并且对Model执行相应的操作; 此时Model变更之后,会把消息通知给事先已经注册过的Presenter, Presenter接收到Model的消息之后,会调用View的相关接口更新页面.
对比MVC模式的由 Model 通知其观察者View来更新视图, 在MVP模式中,View(视图)和 Model(模型)是完全分离的状态,两者通过Presenter进行联系, 此时的观察者是Presenter,被观察者是Model.
优缺点
优点: 1. View可以组件化.在MVP中,View和Model完全分离,View不需要关心业务逻辑的变化,只需要暴露接口给Presenter; 2. 便于测试. 通过Mock一个实现了View接口的对象,放在Presenter中,那么就可以用来测试这些逻辑.
缺点: 1. 由于对视图的刷新操作都放在了Presenter中, 并且一部分业务逻辑的代码也在Presenter中,造成P 变得非常厚重, 维护难度增加.
MVVM
Model–view–viewmodel,简称MVVM.由微软架构师Ken Cooper和Ted Peters开发,通过利用WPF(微软.NET图形系统)和Silverlight(WPF的互联网应用派生品)的特性来简化用户界面的事件驱动程序设计,2005年微软工程师John Gossman在他的博客上发表了MVVM. 它本质上就是MVC的改进版。
MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。重点说一下视图模型(ViewModel).ViewModel的含义就是 "Model of View",视图的模型,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。此外,还引入了一个隐式的一个Binder层, 而声明式的数据和命令的绑定在MVVM模式中就是通过它完成的.
调用关系
MVVM的调用关系和MVP一样。但是,在ViewModel当中会有一个叫Binder,或者是Data-binding engine的东西。以前全部由Presenter负责的View和Model之间数据同步操作,现在交给Binder处理。你只需要在View的模版语法当中,指令式地声明View上的显示的内容是和Model的哪一块数据绑定的。当ViewModel对Model进行更新的时候,Binder会自动把数据更新到View上去,当用户对View进行操作(例如表单输入),Binder也会自动把数据更新到Model上去。这种方式称为:Two-way data-binding,双向数据绑定。可以简单而不恰当地理解为一个模版引擎,但是会根据数据变更实时渲染。
也就是说,MVVM把View和Model的同步逻辑自动化了。以前Presenter负责的View和Model同步不再手动地进行操作,而是交由框架所提供的Binder进行负责。只需要告诉Binder,View显示的数据对应的是Model哪一部分即可。目前,前端开发框架如:VUE.js就是典型的MVVM的架构.
所以,MVVM 模式基本上与 MVP 模式一致。唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
优缺点
优点: 1. 提高可维护性。解决了MVP大量的手动View和Model同步的问题,提供双向绑定机制。提高了代码的可维护性。 2. 简化测试。因为同步逻辑是交由Binder做的,View跟着Model同时变更,所以只需要保证Model的正确性,View就正确。大大减少了对View同步更新的测试。
缺点: 1. 过于简单的图形界面不适用,或说牛刀杀鸡。 2. 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高。
从MVC到MVP再到MVVM,是一个渐进发展的过程.对于应用开发中遇到的问题,经过大量的实践和经验总结,我们总是能找到可行的解决方案.从前到后的仔细想想,对比我们开发的实际项目,希望可以给之前理解模糊的同学带来一些参考和思路.
参考链接
http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
https://zh.wikipedia.org/wiki/MVC
https://github.com/livoras/blog/issues/11
http://www.ruanyifeng.com/blog/2007/11/mvc.html