全端Web开发:使用JavaScript与Java(txt+pdf+epub+mobi电子书下载)


发布时间:2021-02-01 10:50:32

点击下载

作者:萨特诺斯(Casimir Saternos)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

全端Web开发:使用JavaScript与Java

全端Web开发:使用JavaScript与Java试读:

前言

“计算机科学领域只有两大难题:缓存失效和命名。”——菲尔·卡尔顿

写一本关于缓存失效的书并不是难事,难的是如何给书取个合适的名字。本书的书名代表的是Web开发方方面面的变化,这些变化促成了一种新的Web应用设计方法的诞生。

诚然,Web开发的许多方面都可以称为“新”的。不断升级的桌面浏览器、层出不穷的移动终端、一直在演变的编程语言、更快的处理器,还有越来越挑剔的用户以及他们不断增长的、对易用性和交互性的期望,都让开发者枕戈待旦。这些改变使开发者在为项目提供解决方案时必须持续创新。而其中的许多解决方案并不是孤立的,它们有更为深远的含义。

因此,为了响应这些创新,我选择了“客户端-服务器端”这一术语,它在许多方面都反映了Web开发中所发生的变化。时下流行的其他一些对现代化开发实践的描述不适用于我们的研究领域。这里所讲的Web应用开发是有关桌面浏览器的,另一个日渐相关的领域——移动应用开发,则并不包括在内。

人们使用术语单页面应用或单页面界面,来区分现代Web应用和早期的静态网页。这些术语准确地抓住了现代Web应用的特征,和早期应用相比,它们更动态,交互性更强。

当然,很多现代的动态网站并不是单页面应用,它们可能由多个页面组成。这些术语强调的是页面——一个应用的客户端。对于服务器端的开发,它们未作任何特别声明。还有与高度动态化的页面相关的各种JavaScript框架(Angular、Ember和Backbone等),但是这些仍然是客户端的事。我希望本书包含的内容更广,不局限于前端的创新,还应涵盖服务器端的相关设计和Web服务信息传递。

这就是流行的REST(Representational State Transfer)技术,它建议了一种Web服务消息传递的风格。但是REST的作者罗伊·T. 菲尔丁(Roy Fielding)只给出了有限的定义,在个人博客中,他列出了自称为“RESTful APIs”、却常常违反REST风格的几个错误(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)。还有人在StackOverflow上发帖提问JSON API是否是真正的REST式(http://stackoverflow.com/questions/9055197/splitting-hairs-with-rest-does-a-standard-json-rest-api-violate-hateoas),因为JSON并不完全满足REST结构风格的约束。对于REST服务,有一种渐进式描述(http://martinfowler.com/articles/richardsonMaturityModel.html),即只有当API满足相应程度的约束时才可称为REST式。REST将客户端-服务器端架构、动词的使用和URL的命名规范也作为其约束。

使用JavaScript客户端处理实用的“REST式”API产生的消息是开发方法中重要的一环,那么服务器端的情况是怎么样的?

Java企业版(JEE)包含了JAX-RS API(http://docs.oracle.com/javaee/6/tutorial/doc/giepu.html),它是一种Java风格的REST(但没有严格遵循REST规范),并使用了Jersey作为一种参考实现予以展示。如果仅限于使用JAX-RS开发Web应用,则会忽略一些现有的框架和其他一些基于JVM的编程语言所提供的解决方案(尤其擅长快速搭建原型)。

为一本书起一个简单明了、引人入胜的书名并不容易,多亏了James Ward(www.jamesward.com),他在2012年的OSCON大会上发表了一篇题为“Client-Server Web Applications with HTML5 and Java”的演讲。在这篇演讲中,他列举了一种正在变得流行的Web应用开发方法的优点,在近些年的一些项目中,我也使用了这种方法开发Web应用。其中,术语“客户端-服务器端”是理解这种开发方法的关键,它概括了软件架构的根本性改变,对客户端和服务器端做出了明确区分,并将两者放在了同样重要的位置上。

Web应用的这种客户端-服务器端架构带来了程序员工作方式的转变(有时候,甚至是天翻地覆的变化)。本书就是为了帮助开发者适应这种革命而写的,特别是对于如何构建现代Web应用的最新方法方面,也做出了恰当的评价。目标读者

本书的目标读者是那些熟悉Java、HTML、JavaScript和CSS的Web应用开发者。它是为那些喜欢在实践中学习,喜欢将新技术集成进标准工具中构建示例应用的读者而量身定制的。如果你想了解JavaScript的最新发展,以及和使用Java在开发流程上的异同,那么请阅读本书。

阅读本书,你需要在两方面之间做平衡。一方面,读者从本书中能得到的最大收获是从宏观上掌握技术转变的影响和趋势;另一方面,理解技术的最好途径往往是具体的例子。如果你的兴趣在于从宏观上掌握各种技术之间是如何融合在一起,那么定能从本书中受益。

我写作此书的目的,就是帮助读者做出明智的决定。好的决定可以帮助你在新项目中采用正确的技术,避免因采用不相容的技术造成的陷阱,或者对给出的决定形成错误的预期。它还能帮助你在正开发的项目里快速上手,更好地支持已有代码。简言之,明智的决定可以让程序员的工作效率更高,它能让你在当前,或者是未来工作中研究感兴趣的领域时高效地利用时间。本书内容

第1章概览了客户端-服务器端的Web应用架构,介绍了Web应用开发的历史,并为Web开发范式的迁移提供了充足的证据。由此引出了接下来的三章内容,分别描述了开发过程中各种工具的使用。

第2章介绍了JavaScript语言,以及使用JavaScript进行开发时用到的工具。

第3章介绍了如何设计Web API、REST,以及开发基于HTTP的REST式应用时用到的工具。

第4章介绍了Java,以及本书剩余章节内容需要用到的软件。

本书的第二部分探讨了更高级的结构(比如客户端类库和应用服务器),以及它们如何做到良好的分离,从而方便快速开发。

第5章介绍了主流的客户端JavaScript框架。

第6章介绍了Java API服务器和服务。

第7章介绍了快速开发实践。

第8章深入讨论了API设计。

对这些类库和快速开发原型的流程有所了解之后,在接下来的几章中,我们将这些知识应用于具体的项目,使用各种基于JVM的语言和框架。在接下来的两章中,我们使用了轻量级的Web服务器和微框架,而没有采用传统的Java Web应用所需的打包方式和服务器。

第9章介绍了一个使用jQuery和Jython的项目。

第10章介绍了一个使用JRuby和Angular开发的项目。

本书的最后几章详细介绍了几个使用传统的Java Web应用服务器和类库的项目。

第11章介绍了Java生态系统中现有的Web应用打包方式和部署选项。

第12章介绍了虚拟化和在管理大规模服务器环境中涌现出的新技术。

第13章将焦点放在了测试和文档化上。

第14章对全书做总结,并对互联网相关技术和软件开发中各种纷繁的变化给出了看法。

附录A介绍了如何方便地与Java类交互。排版约定

本书使用的排版约定如下所示。● 楷体

表示新的术语。● 等宽字体(Constant width)

表示程序片段,也用于在正文中表示程序中使用的变量、方法名、

命令行代码等元素。● 等宽粗体(Constant width bold)

表示示例中的新代码。● 等宽斜体(Constant width italic)

表示应该由用户输入的值或根据上下文确定的值替换的文本。这个图标表示提示、建议或重要说明。这个图标表示警告或提醒。使用代码示例

你可以在这里下载本书随附的资料(项目、代码示例等):https://github.com/javajavascript/client-server-web-apps。你可以在线查看,或者下载其压缩文件以在本地使用。其中资源是按章划分的。

本书示例代码仅作展示特定功能之用,不求全面展示一个功能完整的应用,具体区别如下。● 产品级的系统要对数据类型、验证规则、异常处理例程和日

志做很大的改进。● 大多数产品级系统都会在后台包含若干个数据存储。为了限

制讨论范围,大多数示例都未牵扯数据库。● 现代Web应用有很大一部分面向移动设备,而且要考虑浏览

器兼容性。除非讨论到这些主题,否则我们会避免响应式设计(http://en.wikipedia.org/wiki/Responsive_web_design),而只提

供一个最简化的设计。● 不可见JavaScript(unobtrusive JavaScript,参见http://

en.wikipedia.org/wiki/Unobtrusive_JavaScript)将CSS、

JavaScript和HTML分开,是一种被广泛接受的最佳实践。然而在

本书的示例代码中,它们常常被混在一起,这是因为对一个应用

来说,仅从一个文件就可窥视其奥秘。● 单元测试和测试代码示例只在和所讨论主题直接相关时才被

包括进来。产品级的系统往往包含大量的测试。

让本书助你一臂之力。也许你需要在自己的程序或文档中用到本书中的代码,但除非大篇幅地使用,否则不必与我们联系取得授权。例如,用本书中的几段代码编写程序无需请求许可,但是销售或者发布O'Reilly图书中代码的光盘则必须事先获得授权;引用书中内容或代码来回答问题也无需获得授权,但将大量示例代码整合到你自己的产品文档中则必须经过许可。

使用我们的代码时,希望你能标明它的出处,但我们并不强求。出处信息一般包括书名、作者、出版商和书号,例如:Client-Server Web Apps with JavaScript and Java , Casimir Saternos (O'Reilly). Copyright 2014 EzGraphs, LLC., 978-1-449-36933-0。

如果还有关于使用代码的未尽事宜,请随时与我们联系:permissions@oreilly.com。对长命令的格式化

对于长命令,我们要做适当的调整以方便大家阅读。在操作系统里有一个约定俗成的规则,即使用反斜杠插入新行。比如,下面的两个命令是等价的,在bash中执行结果是一样的。(bash是一种标准的操作系统shell,当你使用命令行访问Linux服务器或Mac OS X系统时就会用到。)ls -l *someVeryLongName*...ls -l \*someVeryLongName*

这种规则在其他用到操作系统命令的环境下也适用,比如Dockerfiles。

同样,合法的JSON字符串也可以分成多行:o={"name": "really long string here and includes many words"}// 如大家期望的那样,下面的语句结果为真JSON.stringify(o)=='{"name":"really long string here and includes many words"}'// 同样的字符串,分成多行的结果是一样的, 因此下面的结果也为真JSON.stringify(o)=='{"name":' + '"some really long ' + 'JSON string is here' + ' and includes many, many words"}'®Safari Books OnlineSafari Books Online(http://www.safaribooksonline.com)是应需而变的数字图书馆。它同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。

Safari Books Online是技术专家、软件开发人员、Web设计师、商务人士和创意人士开展调研、解决问题、学习和认证培训的第一手资料。

对于组织团体、政府机构和个人,Safari Books Online提供各种产品组合和灵活的定价策略。用户可通过一个功能完备的数据库检索系统访问O'Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology以及其他几十家出版社的上千种图书、培训视频和正式出版之前的书稿。要了解Safari Books Online的更多信息,我们网上见。联系我们

请把对本书的评价和问题发给出版社。

美国:O'Reilly Media, Inc.1005 Gravenstein Highway NorthSebastopol, CA 95472

中国:北京市西城区西直门南大街2号成铭大厦C座807室(100035)奥莱利技术咨询(北京)有限公司

O'Reilly的每一本书都有专属网页,你可以在那儿找到本书的相关信息,包括勘误表、示例代码以及其他信息。本书的网站地址是:http://oreil.ly/client-server-web-apps-js

关于本书的评论和技术性问题,请发送电子邮件到:bookquestions@oreilly.com。

要了解更多O'Reilly图书、培训课程、会议和新闻的信息,请访问以下网站:http://www.oreilly.com

我们在Facebook的地址如下: http://facebook.com/oreilly

请关注我们的Twitter动态: http://twitter.com/oreillymedia

我们的YouTube视频地址如下: http://www.youtube.com/oreillymedia致谢

感谢人员名单如下:● Meg、Ally、Simon和O'Reilly公司的朋友们,感谢你们让我有幸

写作此书。● 感谢我的兄弟Neal Saternos和James Femister博士,他们在我学

习编程早期给我很多中肯的建议。● 感谢Michael Bellomo、Don Deasey和Scott Miller花费了宝贵的时

间审阅本书。● 感谢Charles Leo Saternos从使用Lua开发游戏中抽身出来,帮我

绘制了一些图形并完成了设计工作。● 感谢Caleb Lewis Saternos,从他身上我学到了什么是坚持(有

人坚持晨跑吗?),他完成了本书的编辑工作。● 感谢David Amidon给了我从事软件开发的机会,感谢Doug

Pelletier让我第一次开发了一个基于Java的Web应用。● 感谢那些在项目中并肩作战的兄弟们,他们是经理Wayne

Hefner、Tony Powell、Dave Berry、Jay Colson和Pat Doran,当

然还有首席软件架构师Eric Fedok 和Michael Bellomo。● 感谢PluralSight(http://pluralsight.com/training)的Geoffrey

Grosenbach、Webucator(http://www.webucator.com/)的Nat

Dunn,还有Caroline Kvitka(和来自Oracle和Java Magazine的朋

友),感谢他们在过去几年中给了我技术写作的机会,正是因此

我才得以在今天写出本书。● 感谢我的父母Leo和Clara Saternos在温馨的环境中将我抚养成

人,感谢他们在家用PC还很罕见时为我购置了一台Radio Shack

Color Computer。还要感谢我的妹妹Lori,她时刻提醒我生活中

还有很多重要的事是和计算机编程无关的。

将我诚挚的爱和谢意献给我最棒的妻子Christina和孩子们:Clara Jean、Charles Leo、Caleb Lewis和Charlotte Olivia。在本书写作过程中,他们给予了我无尽的爱与支持,他们总是很有耐心,不断给我鼓励。

最后,巴赫在各个层面上都给予了我灵感。特别是他在开始工作时的专注,我愿和他一同呐喊:荣耀归于上帝(http://en.wikipedia.org/wiki/Soli_Deo_gloria)!第1章因变而变“企业家总在寻求变化,他们适应变化,并把它当作一次机遇。”——彼得·德鲁克,“现代管理学之父”

是怎样的变化促使开发者采用客户端-服务器端的架构?用户行为、技术和软件开发流程的变迁是其中最重要的原因,它们促使开发者改变过去的设计模式。这其中的每个因素,都在以自己独特且有效的方式让已有的模式不合时宜。它们一起激励了相关领域的创新,虽然没有强制标准化,但是在实践中,人们的开发方式正在趋同。

用户变了。早期的Web用户满足于静态页面和最基本的用户界面,而现在的用户期待的是高性能、可交互、精心设计的动态体验。大量新技术的涌现和浏览器能力的扩展满足了用户的期待。现在的Web开发者需要使用工具和新的开发方式,以适应现代Web应用的使用场景。

技术变了。浏览器和JavaScript引擎变得更快。台式机和笔记本性能更强,更不用说无数的移动设备现在也用来网上冲浪了。Web服务API再也不是一个可有可无的功能,而是人们对现代Web应用一个再也正常不过的期望。云计算彻底颠覆了Web应用的部署和运作。

软件开发方式变了。流行的“敏捷宣言”提倡:● 个体和互动高于流程和工具;● 工作的软件高于详尽的文档;● 客户合作高于合同谈判;● 响应变化高于遵循计划。

现在,让Web应用先快跑起来变成可能——至少在小范围内,可以验证技术的可行性。搭建原型价值非凡。正如《人月神话》(The Mythical Man Month,Addison-Wesley Professional)的作者Fred Brooks那句名言所说:“准备着扔掉一个吧,无论如何,你都会这样干的。”原型让早期客户或用户参与交互,帮助在前期确定需求。花几分钟时间编写一个能工作的Web应用已经不是什么不可能的事了。1.1 Web用户

对如何与现代Web应用交互,用户的需求是明确的:● Web应用需能跨平台访问;● Web应用需在不同平台上提供一致的用户体验;● Web应用需响应及时,没有延迟。

高德纳集团(http://www.gartner.com/newsroom/id/1947315)声称,个人云服务将在2014年取代PC机成为人们数字生活的中心。这对Web应用的开发来说有多层含义。用户更加热衷科技,对网站的响应速度有更高的期待。他们不像过去那些年一样被动接受,转而参与其中并互动。网站需要设计得看不出浏览器的局限,提供像原生应用一样的用户体验。

用户希望应用以多种方式提供服务,在不同环境下均可使用。响应式设计、多浏览器、多平台和多设备支持已经成为新的常态。为了支持多样的客户端,使用JavaScript类库和框架至关重要。《纽约时报》最近报道了Web用户对网站响应时间的忍耐度(http://www.nytimes.com/2012/03/01/technology/impatient-web-users-flee-slow-loading-sites.html?pagewanted=all&_r=0)。他们发现:如果某公司网站的访问速度比直接竞争对手的慢250毫秒,那么访问量就会相对少很多。在开发Web应用时,我们需要将性能视作一个关键的考虑因素。1.2 技术

使用Java开发Web应用的开发者,一般都熟悉服务器端的动态内容生成。J2EE和JSP经过完善,变成了JEE和JSF。诸如Spring这样的框架为服务器端开发提供了额外的功能。在Web应用的早期,页面相对来说更静态化,服务器的速度相对更快,JavaScript引擎很慢,处理浏览器兼容性的类库和技术也很少,这种开发模型就是合情合理的。

与之相比,现在的客户端-服务器端架构里,服务器更大程度上负责响应客户端请求,提供资源的访问方式(通常使用XML或者JSON交换信息)。在过去的服务器驱动模型里,页面(和与之相关的数据)都在服务器端生成完毕,一起返回客户端在浏览器里渲染。而在客户端-服务器端架构里,服务器先返回一个包含少量数据的初始页面。用户和页面交互时,页面向服务器端发起异步请求,服务器端则返回消息,以使页面刷新来响应这些事件。

刚开始的Web开发主要是创建静态HTML网站,之后加入了服务器端处理(CGI、Java Servlets),为网站注入了动态内容。慢慢地,人们开始使用更加结构化的语言,集成了服务器端模板(ASP、PHP、JSP)和MVC框架。新近出现的技术继续沿着传统的路子,增加了这样那样的抽象。

为了向开发者屏蔽设计和Web的底层架构,组件化的框架出现了。先是出现了标签库,然后是组件化,几种流行的框架都采用了组件化的方式:● Java Server Faces(JSF)是一种基于XML的模板系统和组件化

框架,导航实行集中化配置;● Google Web Toolkit是另一种组件化框架,它发挥了Java程序员

的长处,让他们集中精力编写Java代码,而不需要直接修改

HTML、CSS和JavaScript。

每一种框架都有它的作用,被成功应用于生产系统。但是,和很多试图屏蔽底层复杂性的方案一样,当你需要更多的控制权(比如想要集成大量的JavaScript代码),或者不满足使用框架的前提条件(比如可用服务器会话)时,就出问题了。Web的基本架构是使用HTTP请求-响应协议的一种客户端-服务器端计算模型,而这些方案却试图去屏蔽它。

浏览器端的创新也促成了责任从服务器端向客户端的转移。20世纪90年代后期,微软开发了后来成为Ajax(Jesse James Garrett于2005年2月18日命名了这一术语)的底层技术。Ajax是“asynchronous JavaScript and XML”的缩写,但是对各种Web页面和服务器进行通信的技术也都适用。这种技术允许少量信息传递,这样在设计基于JavaScript的Web应用时,可以更好地利用带宽。处理器的升级和JavaScript引擎的优化显著地提升了浏览器性能,因此将更多工作从服务器端搬到浏览器端也变得顺理成章。用户界面的响应速度被带向了一个新高度。

移动设备的浏览器更进一步促使了客户端代码和服务器端的分离。有时候,我们可以创建出设计良好的响应式Web应用。如果不行,对所有的客户端设备都使用一致的API这一点也是很吸引人的。

罗伊·T. 菲尔丁于2000年发表的博士论文,让Java EE 6与过去基于组件的API设计背道而驰。人们设计出了JAX-RS(Java API for RESTful Web Services)和Jersey(一个“产品级的参考实现”),用来创建使用REST式风格通信的客户端-服务器端架构。1.3 软件开发

过去,建立一个新的Java项目相当费事。大量的配置选项让人不胜其烦,而且容易出错。几乎没有自动化,人们假设每个项目都不一样,开发者各有各需要满足的需求。

后来的一些创新,让建立项目变得简单很多。“约定优于配置”是来自Ruby on Rails社区的箴言。Maven(http://www.bit.ly/MLOLbU)和其他一些Java项目也选择了有意义的默认配置,并为一些常用案例提供了快速创建方式。

JVM之上出现的各种脚本语言绕过了Java严格的类型检查,加快了开发过程。Groovy、Python(Jython)和Ruby都是弱类型语言,完成同样的功能需要的代码量更少。还有称为微框架的Sinatra和Play,它们提供了最小化的领域专用语言(DSL),用来快速编写Web应用和服务。时至今日,在开发环境中建立一个最小化的Web服务已经不是什么难事。

采用瀑布式开发的大型软件项目失败的案例已经不胜枚举,这充分说明为最终产品搭建一个小型原型有很多优势。搭建原型有以下几个目的:● 验证项目的技术基础;● 为不同技术搭建桥梁,将它们纳入同一结构;● 让最终用户和系统交互,明确系统用途和用户界面设计;● 让系统设计师明确接口和系统之间传递信息的数据结构;● 让程序员能在应用的各个部分并行工作。

原型还有很多优点,如下。● 原型是具体的、实实在在的,它们代表了待设计的最终系统。因

此,原型融入了本应存在于设计文档、图表和其他介质(常常散

见于更随意的场合,比如电子邮件,或人们在饮水机旁的闲谈)

的信息。● 原型是具体的实现。因此,它们代表了真实的需求。这便于人们

更好地理解收集上来的需求,并且确定哪些地方需要进一步明

确。● 原型能迅速暴露可能失败的地方。在具体实现前,失败并不是显

而易见的。● 上述优点能更好地帮助人们理解究竟要做什么,这样就会有更好

的预测和计划。

由于客户端和服务器端分工明确,在搭建原型开发客户端-服务器端的Web应用时可以发挥很大的作用。开发客户端的可以使用服务器端的原型(反之亦然),这样就可以并行开发。即使不并行开发,这样也能快速模拟对服务器端的调用,方便开发客户端代码。1.4 哪些没变

Web的本质没有变(还是基于HTTP进行消息传递的客户端-服务器端架构)。

新技术并没有改变一切。高级编程语言没有抹去了解操作系统的需要;对象-关系映射框架也没有抹去了解关系型数据库和SQL的需要。同样地,在开发Web应用时,人们一直试图效仿桌面应用,想忽略Web的底层架构。

介质特殊性介质特殊性是出现在美学与当代艺术批评中的词汇,但是对技术也适用。它隐含了对于给定的艺术主题,需要使用特定介质来表达的合理性。这个观点由来已久,戈特霍尔德·埃夫莱姆·莱辛在《拉奥孔》(Laocoon: An Essay Upon the Limits of Painting and Poetry)一书中这样写道:物体连同它们看得见的属性是绘画所特有的题材,动作是诗1所特有的题材。2——论诗与画的界限

1节选自朱光潜的《拉奥孔》译本。——译者注

2“论诗与画的界限”是《拉奥孔》译本的副标题。——译者注

当代艺术作品通常挑战艺术上的传统限制。技术是一项创新性活动,但我们关注的是可用的系统,而不是抽象的美。介质无关性之所以重要,是因为如果忽略了平台的本质,则最终系统要么不能以最优的方式工作,要么根本不能工作。这在很多技术领域已经是显而易见的事。本书的目的是提倡遵循Web本身的设计方式来设计Web应用。由于它遵循了Web的基本限制,而不是去忽略它,这样的Web应用才能更好地工作。1.4.1 Web的本质

Web的本质没有变。它依然由服务器和客户端构成,通过HTTP协议,服务器向客户端提供HTML文档,如图1-1所示。

图1-1 HTTP请求和响应

客户端-服务器端的Web应用架构更贴合Web本身的架构。虽然与协议无关,REST是基于HTTP开发的,也和HTTP结合在一起使用。从本质上说,REST定义了使用HTTP的限制。它试图描述一种设计良好的Web应用:该应用是可靠的,运行良好,可扩展,设计优雅,而且方便修改(如图1-2所示)。

图1-2 REST请求和响应

事实上,为了更准确地强调现代Web环境中的挑战,我们还要考虑多设备和云部署,如图1-3所示。

图1-3 多设备和云部署

在Web开发(尤其是组件框架)中,Web的无状态、客户端-服务器端结构的本质,成了被忽略的“介质特殊性”。1.4.2 为什么说服务器驱动的Web开发有害

具备某种功能,不意味着要使用该功能。在很多情况下,服务器驱动、基于组件的Web开发方式都应被客户端-服务器端的架构替换。服务器驱动的方式模糊了Web的本质,它本身就是一种架构于HTTP协议之上的客户端-服务器端模型。忽略或模糊Web的本质,会让开发、调试和支持软件系统变得更难。服务器驱动的Web原本是为了让Web变得更容易理解,但这一意愿很快在所有正式的系统(需要对其具备的功能和工作方式有清晰理解的系统)里被打破。

被认为是有害的

1968年, Edsger W. Dijkstra发表了一封题为“Go To语句被认为是有害的”(Go To Statement conidered Harmful)的公开信。这封信很有趣,除了对结构式编程中减少使用goto语句造成很大影响,它还把“被认为是有害的”(considered harmful)这一说法带入到极客文化中。Tom Christiansen认为使用csh编程是有害的(http://harmful.cat-v.org/software/csh),Douglas Crawford(道格拉斯·克罗克福德)发表了一篇题为“with语句是有害的”(“with Statement Considered Considered Harmful”,参见http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/)的博文。该说法还见于其他地方,包括Eric A. Meyer发表的那篇风趣的自我指涉的文章“‘被认为是有害的’系列文章是有害的”(“'Considered Harmful' Essays Considered Harmful'”,参见http://meyerweb.com/eric/comment/chech.html),而且可以想见,这个说法还会不停地出现。

尽管“被认为是有害的”这类博人眼球的文章质量上参差不齐,但其都有一个合理的共识:具有一种语言特性或一个技术解决方案,不过这并不表示它是好的、长久的解决方案。1.5 为什么需要客户端-服务器端的Web应用

在Web开发中,客户端-服务器端的架构有很多优点。1.5.1 代码组织结构/软件架构

将代码按逻辑解耦的好处很明显,它增强了原有结构和后续支持系统的内聚性。将客户端和服务器端分层,这可以让代码变得可管理、模块化。另外,数据和显示标记能更清晰地分离。可以使用JSON而不是内嵌的方式发布数据,这和现代JavaScript的不可见JavaScript概念是一致的,页面的行为、结构和表现分离。

好的代码组织结构自然会带来灵活性和代码重用。在应用的整个生命周期内,灵活性表现在很多阶段,不同的代码可以分开开发(暴露新的API、创建移动客户端、测试和发布应用的新版本,这些都可以是独立的)。有了清晰的组件,我们才能更好地重用代码。至少,同一份RESTful API可供不同的浏览器和移动设备使用。

组件化的方式易于引入脆弱的耦合,适配性也不好,很难插入不同的前端。1.5.2 “设计的灵活性”与“使用开源API”

组件化的方式包括了高度集成的服务器端代码,这些代码要求了解特定的JavaScript技术。从设计和行为的角度看,生成的HTML和CSS限制了选择性。一个单独运行JavaScript的客户端能使用最新的类库,简化浏览器兼容性、标准化DOM操作,并提供复杂的小组件。1.5.3 原型

由于分层清晰,为客户端-服务器端的Web应用搭建原型很方便。正如前面提到的,原型可以测试和验证初始想法,帮助澄清模糊的概念,方便清晰地交流需求。用户和这种更具体的东西交互能产生新的想法,这远比冗长的文字描述或图片有用得多。原型还能帮助用户快速地认识,纠正错误的想法和不一致性。如果正确使用,原型能帮助节省时间、金钱和资源,最终产生一个更好的产品。1.5.4 开发者的效率

除了可以分别(或同时)搭建客户端和服务器端的原型,工作也能清晰地拆分,从而进行并行开发。这种隔离让代码能分开编写,这就避免了模块化方式中页面一更改就得构建整个服务器端代码的问题。开发任务花的时间和精力变少,更改也没有原来复杂,故障诊断也变得简单了。

当需要替换、升级或重新分配服务器端代码时,这点变得尤其明显。这样的改动可以独立完成,不会影响客户端。唯一的限制是原来的接口(特别是URL和数据结构)需要保持可用。1.5.5 应用性能

页面的感知性能对用户体验影响极大。更快的JavaScript引擎让客户端可执行计算密集型操作,从而将服务器的工作负荷转移到客户端。Ajax技术能够按需请求较少的数据,这避免了对整个页面的频繁刷新,请求中传输的数据也减少了。用户和应用交互时,反应更及时,体验更流畅。

无状态的设计让开发者和技术支持的工作更轻松。用于管理会话的资源可以得到释放,这简化了负载均衡和配置。服务器很容易被加进来以应对增长的负荷,方便了水平扩展。而且,这还取代了传统的、通过升级硬件提高吞吐量和性能的流程,那种流程真让人头疼。

优点还不止于此,它从整体上简化了系统架构。比如,在云环境中维持状态是件非常有挑战性的事。如果使用传统的有状态会话,高效地持久化数据是个问题,如何才能在一个用户会话的多个请求中保持数据的一致?如果数据存储在后台的一个服务器中,后续被分配到其他服务器的请求就无法访问该数据,可能的解决方案有如下。● 使用支持集群和故障转移功能的应用服务器,以Weblogic为

例,它使用了托管服务器的概念。这种解决方案需要额外的管理

工作,每个应用服务器的实现方式也不同。● 使用会话关联或粘滞会话(sticky session),此时一个用户

会话内的所有请求都被发送到同一个后端服务器,但是不提供自

动故障转移功能。● 使用集中的数据存储。通常都是将数据持久化到数据库中,

这种方式的性能不好。● 将数据存储在客户端。这避免了将会话数据存储到数据库的

性能问题,也解决了使用粘滞会话带来的故障转移问题,因为任

何一个后端服务器都能处理来自客户端的请求。

避免管理服务器端状态的做法越来越流行,甚至像JSF这样原来被设计成传统的服务器端管理用户会话的框架,现在也加入了支持无状态的功能。

创建客户端-服务器端的应用有一些不可避免的挑战。我们有必要将JavaScript看作头等开发语言,这意味着需要深入学习该语言、使用现有类库,以及借鉴成熟的开发技巧。原来被普遍接受的一些架构技术需要重新设计,比如管理会话的标准实践。对客户端-服务器端的Web应用并没有定义良好的标准。JEE的某些部分(比如JAX-RS)澄清了一些概念,但其他框架(如JSF)并未遵循这些定义。

越过了初期学习(和忘记原有知识)曲线,使用客户端-服务器端的模式搭建Web应用就变得异常高效和稳定。对服务器端和客户端职责的清晰划分,让修改和扩展代码变得更容易。对于Web本质的清楚认识减少了模糊设计带来的问题,水平扩展的能力也大大超出了使用其他设计所能带来的效果。1.6 小结

新的挑战带来新的机遇。客户端-服务器端的架构设计是对Web和Web开发变化做出的理所应当的响应。它清楚什么没有改变,因而能够指导人们开发出稳定、持久的解决方案,为后续的增强打好了基础。第2章JavaScript和JavaScript工具“JavaScript是最受轻视的语言,因为它不是其他语言。如果你擅长其他语言,但现在必须在只支持JavaScript的环境里工作,那么你必须使用JavaScript,这真是太烦人了。在这种情况下,大多数人一开始不屑于学习JavaScript,随后却会惊讶地发现JavaScript和他们原本想要使用的其他语言差别如此之大,而且这些差别非常重要。”——道格拉斯·克罗克福德

道格拉斯·克罗克福德(Douglas Crockford)将JavaScript总结为一门很多人使用却鲜有人学习的语言。他写了一本书,列举了该语言的合理用法和强大功能,同时指出了存在问题、需要回避的部分。如果你需要经常使用JavaScript,应该花时间和精力全面学习。道格拉斯·克罗克福德忽略了该语言中的很多功能,将精力集中在一个强大、简洁的子集,这种方式能帮助程序员更好地学习JavaScript。

除了学习JavaScript语言本身(后来被标准化,称为ECMAScript),还需要花时间学习特定的编程环境。其他语言运行在操作系统、关系型数据库或宿主应用之上,而JavaScript最初被设计成在浏览器上运行。ECMAScript语言规范(http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)明确指明了这点。ECMAScript最初被设计成一门Web脚本语言,提供了一种让浏览器里的页面更加生动的机制,并且将基于Web的客户端-服务器端架构中一些服务器端的计算任务交给浏览器。——ECMAScript语言规范

核心JavaScript语言需要结合两个不同的API来理解:浏览器对象模型(BOM)和文档对象模型(DOM)。浏览器对象模型包含window对象及其子对象:navigator、history、screen、location和document。document对象是文档对象模型的根节点,是页面内容结构的一个树状表示。一些对JavaScript的抱怨其实是针对浏览器对象模型和文档对象模型的实现问题而言的。不能全面理解这些API,就不能有效地在Web浏览器里进行JavaScript开发。

本章剩余部分介绍了在浏览器里使用JavaScript进行开发需要了解的主要内容。这个介绍不够全面,只是强调了读者想要深入了解这门语言所需掌握的入手点和知识点。2.1 学习JavaScript

教学中广泛采用了Java作为编程语言,和其有关的认证也已经存在了很多年,因此和Java相关的知识已经被充分理解、标准化,成为通识了。人们经常在学校里就学过Java,工作后又经过自学取得了相关认证。同样的情况并没有发生在JavaScript上,但还是有一些关于JavaScript的好书可以帮助大家学习的。● JavaScript: The Good Parts(http://shop.oreilly.com/

product/9780596517748.do,O'Reilly出版),道格拉斯·克罗克福

德著,该书在前面已经提到过。在圈子里,就某些问题对道格拉

斯·克罗克福德提出异议已经成为一种时尚,那是因为他是公认

的权威,他帮助很多JavaScript开发者形成了自己的思想。有时

候,他提出一些过于严格的“法则”,但是如果你不了解

JavaScript语言的子集(他认为属于“好的部分”)和他尽力避免

使用的部分,那就是自讨苦吃。● Secrets of the JavaScript Ninja(http://www.amazon.com/

Secrets-JavaScript-Ninja-John-Resig/dp/193398869X,Manning

Publications出版),John Resig、Bear Bibeault著。John Resig是

jQuery之父,他对现实中和浏览器兼容性、操作DOM相关的挑战

有着深刻的理解。● 还有一些书类似于标准语言的参考手册,包括JavaScript:

The Definitive Guide(http://shop.oreilly.com/

product/9780596805531.do,O'Reilly出版)、Professional

JavaScript for Web Development(http://www.amazon.com/

Professional-JavaScript-Developers-Nicholas-Zakas/

dp/1118026691,Wrox Press出版,Nicholas C. Zakas 著)。它

们比前面两本书内容更全面(作者的个人观点也少)。它们可能

不是那种需要从头读到尾的书,但是在深入某个具体的主题时却

是非常有用的。

本节不打算重复你在上述书或其他书中所能学到的全部内容,而是帮助你上手,评估自己的JavaScript知识。本章还会引用其他书籍和资源,如果你碰到想要深入研究的术语或概念,可参考它们。

自觉阶段

学习过程中的关键一环是知道自己知道什么,以及知道自己能够知道什么。达克效应(http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect)是一种认知上的偏差,它描述了这样一种倾向:低技能的人错误地认为他们的能力高于平均水平。鉴于围绕JavaScript的困惑和其被嘲笑为一种“玩具语言”的频率,本节的目标(和自觉阶段学习模型相关;自觉阶段学习模型参见http://en.wikipedia.org/wiki/Four_stages_of_competence)旨在让读者意识到要学些什么。2.2 JavaScript的历史

关于JavaScript的历史已有详尽的记录,Brendan Eich在1995年用10天时间写出了JavaScript的初始版本(http://www.w3.org/community/webed/wiki/A_Short_History_of_JavaScript)。但如果将JavaScript放在计算机科学的历史里来考量,尤其是和现存第二古老的高级程序语言Lisp相联系,应该会更有意义。John McCarthy在1958年(比Fortran晚一年)发明了Lisp,这是一种计算机程序的数学表达。Scheme是Lisp两种主要的方言之一。奇怪的是,尽管和其他语言的设计反差强烈,Scheme却在JavaScript的历史里扮演了异常重要的角色。图2-1列出了一些影响了JavaScript设计的主要语言。

图2-1 JavaScript语法继承关系

Scheme极简主义的设计风格并没有体现在JavaScript中,JavaScript相对冗长的语法来自其他语言,这点在JavaScript 1.1规范(http://hepunx.rl.ac.uk/~adye/jsspec11/intro.htm#1006028)中有所提及:JavaScript的语法大多来自Java,同时继承了Awk和Perl的一些语法,其基于原型的对象模型间接受到Self的影响。——JavaScript 1.1规范

这和Scheme截然相反,Scheme的语法没有受多种语言的影响。Perl直接影响了JavaScript的某些部分,比如对正则表达式的支持。然而Perl的箴言:不止一种方法去做一件事(TMTOWTDI,“there's more than one way to do it”,参见http://en.wikipedia.org/wiki/There's_more_than_one_way_to_do_it)可能在更广的范围上影响了JavaScript。至少可以反过来说,“只用一种方式去做一件事”(在Python社区里很流行)并不适用。请看如下创建和初始化数组的不同方式:var colors1 = [];colors1[0] = "red";colors1[1] = "orange";var colors2 = ["yellow", "green", "blue"];var colors3 = new Array(2);colors3[0] = "indigo";colors3[1] = "violet";var colors4 = new Array();colors4[0] = "black";colors4[1] = "white";

因此,看起来JavaScript(及其受到多种语言的影响和语法上的变种)和Scheme(Lisp的极简方言)之间似乎没有任何关联。但是,JavaScript的确和Scheme关系紧密(http://brendaneich.com/tag/history/),直接受其影响:就像我常说的,Netscape的其他人也可以作证,我受雇于Netscape时承诺“在浏览器里使用Scheme”。——Brendan Eich

这一点也反映在ECMAScript语言规范(http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)里:ECMAScript中的一些技术和其他编程语言使用的类似,尤其是Java、Self和Scheme。——ECMAScript语言规范

来自Scheme的影响也被其他人辨认出来了。道格拉斯·克罗克福德根据Daniel Paul Friedman那本经典书The Little Schemer(http://mitpress.mit.edu/books/little-schemer,MIT Press出版),写了一篇文章“The Little JavaScripter”(http://www.crockford.com/javascript/little.html,列举了Scheme和JavaScript的共同点。Lisp社区(欧洲Lisp研讨会,参见http://www.european-lisp-symposium.org/)也将ECMAScript描述为一种“Lisp方言”。JavaScript和Scheme语言之间的相似性不可否认,这是由创造者的本意决定的。2.3 一门函数式语言

Java开发者倾向于站在面向对象的角度解决问题。尽管JavaScript也支持面向对象,但是这却不是解决问题最高效的方式。使用JavaScript的函数式编程能力会更高效。理解了什么是函数式编程和它的含义,就弄清楚了这门语言的本质和能力。

JavaScript和Scheme语言相像的主要特征是它是一门函数式编程语言,这既和它的起源相关,也和它的语法相关。这里的函数式编程语言是指既支持函数式编程(http://en.wikipedia.org/wiki/Functional_programming),又支持将函数当作一级对象(http://en.wikipedia.org/wiki/First-class_function)。JavaScript的这一基本概念为语言的其他方面提供了方向。对很多程序员,尤其是那些以类似Java这样还未直接支持函数式编程的语言为基础的程序员来说,使用1函数式编程是非常大的范式迁移。

1函数式编程在JVM上已经存在一段时间了,使用过一些基于JVM的脚本语言,包括Rhino JavaScript实现。Java 8计划加入Lambda表达式、闭包和相关语言特性。Java 8还会加入一个新的

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载