Web前端的三种架构模式

开课吧开课吧锤锤2021-06-25 16:29

    本文要介绍的主要有三种架构模式:Middleware,MVC,DI。

web

    Middleware中间件模式

    相信做过Node.js服务端开发的同学对这个模式一定不陌生,考虑如下Web应用的场景:

web

    在一个简单的HTTP请求响应周期里,有如下条件处理,

    记录开始时间

    需要验证用户的身份authentication。

    解析cookie并加载body

    根据路由返回不同的业务处理结果

    没有命中路由则返回404页面

    记录日志

    记录总共花费时间

    处理异常并显示页面(开发环境)

    有些处理会根据是否成功决定是否继续后面的粗粒,有些处理会生成额外的数据,还有的要求拦截某些处理的开始和结束,最后异常处理和记录日志要求一定被执行。

    一般的解决方法是用嵌套条件判断结合trycatchfinallyreturn等控制语句,但是这样的方案会导致代码碎片化和复制粘贴的编码风格,因为控制流和逻辑耦合到了一起。理想的方案应当如下:

    中心化控制流

    解耦处理模块(重用性)

    声明式、可配置的服务(配置和代码无关)

    这些场景由来已久,很久以前J2EE总结了InterceptingFilter模式,有兴趣大家可以看看这篇文(lun)章(wen),里面由浅入深提到三种方案,其中最初级的方案代码如下:

public class DebuggingFilter implements Processor {

  private Processor target;

  public DebuggingFilter(Processor myTarget) {

    target = myTarget;

  }

  public void execute(ServletRequest req,

  ServletResponse res) throws IOException,

    ServletException {

    // preprocess

    target.execute(req, res);

    // post-process

  }

}

    这个和express和Koa的中间件模式极其相似,但是因为静态语言本身一些特征,导致最后形成的企业级代码极其繁琐,并且有许多局限性。最主要的问题是处理模块之间难以重用和共享数据,因为ServletRequestServletResponse无法动态添加属性。以至于JavaEE把这个模式的适用性加了许多限制,包括和核心处理逻辑分开。

    在动态语言的世界里面,我们可以很方便的往req和res里面添加数据(基于约定),因为没有了很多OOP世界里面的”束缚“,Node.js的实现通常更加优雅和通用。

    Express中间件模式

    express实现如今广泛接受的Middleware中间件模式。中间件的意思是在请求和响应中间执行的函数(为了区分另一个中间件),签名如下:

var express = require('express');

var app = express();

web

   这个模式包含了一套声明式的路由规则,和middleware函数上的next签名,它们共同构成了整个中间件模式的控制流,如图:

web

    这个模式的核心构成不是权限,解析等中间件逻辑,而是路由判断,next和中断响应(验证失败、解析失败),其作为中间件执行控制,解耦了具体的处理逻辑,使得更容易写出通用的细粒度的中间件。express内置的强大的声明式路由,并且路由和middleware分离可以说是它最成功的设计之一。

    然而在一些稍微复杂点的业务中,比如一个网站有管理端和用户端,两个端相当于独立的app。express4.0提供了一个非常强大的功能Router。Router拓展了链式决策变成树形决策,可以让express更好的支持大型项目。

/*
   文件 bird.js
*/
var express = require('express')
var router = express.Router()

router.get('/', function (req, res) {
  res.send('Birds home page')
})

module.exports = router

/*
   文件 app.js
*/

var birds = require('./birds')

// ...

app.use('/birds', birds)

web

    Koa异步中间件模型

    Koa的异步中间件模式-洋葱模型,相比Express,其中间件函数返回Promise,支持async/await,并且可以轻松实现前置和后置的处理。毫无疑问这个模式更加先进,一些在express里面不好实现的拦截处理逻辑,比如异常处理和统计时间,在Koa里用一个中间件就能搞定。然而遗憾的是Koa本身只提供了Http模块和洋葱模型的最小封装.web

    未来我看好Koa,其实express也意识到这点,他们计划在5.0版本里添加Promise的支持,然而作为一个老牌和完整生态的框架,要克服的困难远不是技术层面上看似的简单,直到目前仍然没有看到5.x宣布支持Promise,让我们拭目以待。

    MVC模式

    MVC模式也需要介绍吗,我们天天都在聊MVC,不管前、后端框架,说一句MVC,对一下眼神,基本确定对方懂你了。

    事实是,前端框架已经不适合用MVC讨论,这个模式从1979年提出以来,作为万精油模式,在各个框架和场景中被套用,背负了太多的历史包袱,大家可以看winter的文章谈谈UI架构设计的演化。拨乱反正我觉得有希望,讨论前端框架大家以后统称MV模式就好了,就是模型和视图分离。

    我们今天要讲的MVC模式是指在服务器上(后端)MVC模式,它的定义经受了时间和实践的检验,在许多企业级Web框架的实现中高度一致。先列举场景:

    如果你的网站只有几个简单的页面,所有逻辑都写在Controller里面,是没有问题的。随后网站迅速的增长,你发现,

    许多页面里面的视图是一致的,但是背后的数据模型不一致。比如:网站上几乎没有一个视图或者组件是独一无二的,表格,下拉框等。

    许多页面里面的数据模型是一样的,但是展现的视图不一致。比如:同时支持PC和移动端,国际化本地化。

    我们做一个数学模型模拟极端情况,大家很容易能看到问题

wevb

    假设左边是我们的系统最终的样子,它刚好可以表示成M(模型)和V(视图)的内积,我们更倾向于右边的表达,因为它更简洁而且没有重复。这里的内积操作大家就可以理解成控制器,实际上不会如此巧合,但是分离模型和视图帮助我们提高代码复用,降低设计复杂度的好处是很显然的,一个更通用的表达

web

    模型视图和控制器之间都是单向链接,所以整个系统的行为非常可控且容易测试,单独把路由分开是想强调Router和Controller是两个概念,Router只是一个触发器(或者提供了一种映射关系),在写测试的时候,我们也可以跳开Router单独调用Controller。

    看到上面的两种模式,是不是已经开始想,那有没有一个框架同时是Koa+Router+MVC呢,推荐大家一个非常好用的企业级Web框架ThinkJS3.0,最新版的ThinkJS集成了大量最佳实践和完善的文档,不管是学习或者企业级开发都非常推荐。而且ThinkJS同样实现了接下来要讲的模式。

    DI依赖注入模式

    还是先说场景,假如服务端需要实现session,前期考虑到成本和用户量,单台服务器存到文件就够用了。后期如果用户量大的时候,需要横向扩展(Scale-out),就把session实现基于中心化的Redis服务。

    我们系统设计目标是:

    不需要修改业务逻辑代码实现替换

    不需要关注服务的创建和生命周期

    解决这类系统扩展性问题有一个非常著名的设计原则控制反转(IoCInversionofcontrol),而依赖注入(DIdependencyinjection)就是其中的一个实现模式。

    DI的基本思路是这样,首先我们的代码不能依赖具体的服务,需要总结归纳出一套抽象接口,业务实现依赖接口,而服务实现接口,最后通过框架专门负责创建和提供接口的实例。

web

    这里的IoC容器或者说Ioc框架,会在启动的时候读取配置文件,并在运行的时候根据需要创建实例提供给使用者,在静态语言如java,c#需要用到反射等高级语法,而JavaScript本身是动态的,接口基于约定,并且使用的方式也更加灵活。比如ThinkJS3.0里面的extend和adapter就可以理解成接口和实现,如图:

web

    那之所以称为extend,是因为框架会直接把接口注入(mixin)到controller或者think对象中。这样的好处是使用起来更方便,缺点是不同extend需要约定好不能重名。

    以上就是开课吧广场小编为大家整理发布的“Web前端的三种架构模式”一文,更多Web教程相关内容尽在开课吧广场Web教程频道!

免责声明:本站所提供的内容均来源于网友提供或网络搜集,由本站编辑整理,仅供个人研究、交流学习使用。如涉及版权问题,请联系本站管理员予以更改或删除。
有用
分享
全部评论快来秀出你的观点
登录 后可发表观点…
发表
暂无评论,快来抢沙发!
云开发实战特训营