大规模的JavaScript: 单一的服务层

开发 前端
当我在开始架构一个JS 应用的原型时,我总是尝试把这些组件设计成既能被Backbone.js应用使用也能被一次性的脚本或者工程使用的结构。这些结构性的组件增长十分迅速,他们变得十分庞杂。在这篇文章中,我将会研究后端API服务层的动机,优点,缺点以及建议或者头脑风暴他们的代替实现方式。

当我在开始架构一个JS 应用的原型时,我总是尝试把这些组件设计成既能被Backbone.js应用使用也能被一次性的脚本或者工程使用的结构。这些结构性的组件增长十分迅速,他们变得十分庞杂。在这篇文章中,我将会研究后端API服务层的动机,优点,缺点以及建议或者头脑风暴他们的代替实现方式。

后端API服务层

尽管你可能实现了你的后端API(MVC或者别的方式),但是记忆和重复实现API的细节是非常笨重的。当一个团队成员说他们开发一些东西需要登录功能,他们是需要重复造轮子还是你给他们一个预编译的JS函数调用呢?

我希望建立一个名字为younow.js的JS客户端来解决这些问题,这将允许任何JS应用和我们的后台交互。有一个新增的需求需要登录功能?不用担心! 只要调用YouNow.Api.login()并且绑定处理函数就行。在这个例子中,服务层有着暴露在YouNow.Api命名空间的登录函数。

  1. YouNow.Api.login() 
  2.   .done(function (loginData) { 
  3.     // Do what you need with the login data 
  4.   }) 
  5.   .fail(function (errorMsg) { 
  6.     // Handle the error as you wish 
  7.   }); 

注意:为了实现JS服务层,如果你不喜欢JQuery的回调模板,你可以替换用于接收成功/失败回调的函数。我个人是喜欢这样链式/管道的回调方式和标准接口。对于不喜欢这种方式的人,我也说一句你好。

听起来不错,不是吗?

优点:对于每一个YouNow.Api命名空间内的结点,服务层younow.js将会有一个关于预期参数和被隐藏的复杂机制的文档说明。尤其是使用服务 的用户不用去担心这个请求是GET还是POST,是通过CDN返回还是我们直接发送的,更不用担心怎样去构建URL和如何处理jsonp数据。对于一个单 点来说,所有的后台交互都是孤立的。

缺点:这个文件的增长迅速,几乎超出你的想象。对于每一次后台调用,我们需要一个增加新的YouNow.Api的结点。你可以抽象业务到helper函数 中来处理响应,jsonp,cdn地址和$.ajax调用。然而,对于一个应用来说,这个文件已经达到40kb了。每一个应用有自己的API结点集,每一 个都和younow.js交互。这对于维护来说是非常困难的。

现在想象一下,一个简单的小应用程序,如媒体播放器( 例如一个JS的包装器,JWPlayer的初始器)。它可能需要一个或两个接口(登录的接口和 检索广播信息的接口)。那么它必须下载整个40KB的数据包。

另一种实现1:为每个应用程序分配一个服务层

常规的服务层可以是简单的辅助函数的关键集合 (ajax,CDN,约定)每一个应用程序在加载自身的服务层函数将继承YouNow.Api命名空间。

好处:这解决了主服务层不断膨胀的问题。

好处:坚持什么时候以及如何扩展一个应用程序的命名空间的原则,该解决方案可以清晰地扩展出多种应用程序。

缺点:每一个应用程序的个性化服务层可能变得非常臃肿。

缺点:如果两个应用程序都对同一个端点接口有共同的需求时,怎么办?

  1. // loginservice.js 
  2. YouNow.Mixins.LoginService = { 
  3.   login: function () {}, 
  4.   logout: function () {} 
  5. }; 
  6.   
  7. // broadcastservice.js 
  8. YouNow.Mixins.BroadcastService = { 
  9.   get: function () {}, 
  10.   deletefunction () {} 
  11. }; 

另一种实现3:完全脱离服务层。将交互转移到模块内完成

因为服务层的存在,想要和后台进行交互的Backbone模块只需要简单的调用YouNow.Api离得函数就行。现在这些模块的实现是精简的,但是你也能够理解这些模块其实不必传输自己的数据到别的地方。感觉就像是模块应该拥有那种功能。

完全脱离服务层,我们将会有一个拥有登陆/登出功能的用户模块和完全实现(或许是基于基本模块的扩展,这样我们能够脱离CDN和ajax helper)。

优点:各模块拥有适当的功能。

缺点:随着时间推移,越来越多的函数充斥着这个模块。不是很确定这是否是一个缺点,因为对于“胖模型”来说,这也许就是一个优点。

【更新】缺点:如果小的应用想要实例化你的模块现在需要Backbone(或者其他你在使用的框架)和它的依赖模块,很不幸,将会为模块的臃肿付出点代价,但是这可以作为你的系统统一化的一个折中方案。

任何想要使用登陆/登出功能的应用都必须要实例化一个用户模块。这并不令人讨厌。举个例子,多媒体播放器应用需要登陆一个用户。那么现在有一个你的用户,是一个用户模块的实例。现在就可以调用它的登陆功能了。与之相比,不用去直接调用YouNow.Api.login()。

优点:服务层变成了一些了经过封装的结点。数量的增长将会体现在两个方面:封装的数量和函数的数量。单层结构只会在一个方面增长,所以这个方案有更好的伸缩性。

我现在正在想弥补这个方案的缺点,这也成为第三种最好的实现方式,但是我十分喜欢这种方式;通过下面的第三种实现方式,它修复了模块的过度膨胀问题。

如果你发现这个方法的巨大缺陷,请给我留言。

通过上面的第二种实现方式(封装方式),用户模块将不会拥有登录/登出功能。反而,它将会封装登录服务,也许使用Cocktail.js——我也是这个项目的维护者之一;)。

这可以间接的访问。我的意思是,你查看用户模块的定义,找不到登录/登出方法。那么如何一眼看出用户模块有那中功能呢?从技术上说,我们传递数据到另一个服务,登录服务获得在封装好的用户模块的数据,这样就实现了用户模块自己的登录功能。

什么是最好的解决方案?

我认为解决方案其实就是实现方式2和3的混合体。

在目前,服务层是一个好的想法,但是不能满足复杂应用的伸缩性。目前,我已经迁移到胖模块的实现(第三种方式),但是还没搭配使用分组封装(第二种方式)。

或许还有别的实现思路?

原文链接:http://www.oschina.net/translate/large-scale-javascript-a-monolithic-service-layer

责任编辑:陈四芳 来源: 开源中国编译
相关推荐

2010-07-15 09:53:02

云计算计算网络

2017-12-14 14:36:54

金融工具敏捷大房间计划

2023-01-03 08:05:00

无服务器扩展架构

2020-08-25 10:34:22

微服务微服务架构生产环境

2017-09-27 13:56:58

微服务架构故障网络

2024-01-10 18:49:47

2023-06-30 17:59:27

Ray离线推理

2012-11-05 10:08:01

苹果iCloud云应用

2009-01-09 23:13:00

2022-09-16 15:53:56

智慧城市物联网通信

2022-04-26 14:17:37

网络攻击黑客网络安全

2024-09-26 10:41:31

2015-04-28 15:31:09

2011-08-03 09:15:47

存储内存云云计算

2015-07-09 16:35:02

2014-05-19 10:26:34

2013-05-14 13:30:08

部署SaaS云计算

2021-09-24 10:31:04

安全网络钓鱼微软

2019-04-18 11:37:49

NameNodeHDFS架构

2013-05-16 10:02:43

SaaS云计算部署
点赞
收藏

51CTO技术栈公众号