不管前端也好,后端也好,都是整个软件体系的一部分。软件产品也是产品,它的研发过程也必然是有其目的。绝大多数软件产品是追逐利润的,在产品目标肯定的状况下,成本有两个途径来优化:减小部署成本,提升开发效率。html
减小部署成本的方面,业界研究得很是多,好比近几年很流行的“去IOE”,就是很典型的,从一些费用较高的高性能产品迁移到开源的易替换的产品集群,又好比使用Linux + Mono来部署.net应用,避开Windows Server的费用。前端
提升开发效率这方面,业界研究得更多,主要途径有两点:加快开发速度,减小变动代价。怎样才能加快开发速度呢?若是咱们的开发不是从新造轮子,而是每一次作新产品均可以利用已有的东西,那就会好不少。怎样才能减小变动代价呢?若是咱们可以理清模块之间的关系,合理分层,每次变动只须要修改其中某个部分,甚至不须要修改代码,仅仅是改变配置就能够,那就更好了。git
咱们先不看软件行业,来看一下制造行业,好比汽车制造业,他们是怎么造汽车的呢?造汽车以前,先设计,把整个汽车分解为不一样部件,好比轮子,引擎,车门,座椅等等,分别生产,最后再组装,因此它的制造过程能够较快。若是一辆汽车轮胎被扎破了,须要送去维修,维修的人也没有在每一个地方都修一下,而是只把轮胎拆下来修修就行了,这个轮胎要是实在坏得厉害,就干脆换上个新的,整个过程不须要不少时间。github
席德梅尔出过一款很不错的游戏,叫作《文明》(Civilization),在第三代里面,有一项科技研究成功以后,会让工人工做效率加倍,这项科技的名字就叫作:可替换部件(Replacement Parts)。因此,软件行业也应当引入可替换的部件,通常称为组件。web
在服务端,咱们有不少组件化的途径,像J2EE的Beans就是一种。组件建造完成以后,须要引入一些机制来让它们可配置,好比说,工做流引擎,规则引擎,这些引擎用配置的方式组织最基础的组件,把它们串联为业务流程。无论使用什么技术、什么语言,服务端的组件化思路基本没有本质差异,你们是有共识的,具体会有服务、流程、规则、模型等几个层次。bootstrap
早期展现层基本以静态为主,服务端把界面生成好,浏览器去拿来展现,因此这个时期,有代码控制的东西几乎全在服务端,有分层的,也有不分的。若是作了分层,大体结构就是下图这样:后端
这个图里,JSP(或者其余什么P,为了举例方便,本文中相关的服务端技术都用Java系的来表示)响应浏览器端的请求,把HTML生成出来,跟相关的JavaScript和CSS一块儿拿出去展现。注意这里的关键,浏览器端对界面的形态和相关业务逻辑基本都没有控制权,属于别人给什么就展现什么,想要什么要先提申请的尴尬局面。设计模式
这个时期的Web开发,前端的逻辑是基本可忽略的,因此前端组件化方式大同小异,不管是ASP仍是JSP仍是其余什么P,均可以自定义标签,把HTML代码和行间逻辑打包成一个标签,而后使用者直接放置在想要的地方,就能够了。浏览器
在这一时代,所谓的组件化,基本都是taglib这样的思路,把某一块界面包括它的业务逻辑一块儿打成一个端到端的组件,整个很是独立,直接一大块从界面到逻辑都有,并且逻辑基本上都是在服务端控制,大体结构以下图所示。前端框架
自从Web2.0逐渐流行,Web前端已经再也不是纯展现了,它逐渐把之前在C/S里面作的一些东西作到B/S里面来,好比说Google和微软的在线Office,这种复杂度的Web应用若是还用传统那种方式作组件化,很显然是行不通的。
咱们看看以前这种组件化的方式,本质是什么?是展示层跟业务逻辑层的隔离,后端在处理业务逻辑,前端纯展示。若是如今还这么划分,就变成了前端有界面和逻辑,后端也有逻辑,这就比较乱了。咱们知道,纯逻辑的分层组件化仍是比较容易的,任何逻辑若是跟展示混起来,就比较麻烦了,因此咱们要把分层的点往前推,推到也能把单独的展示层剥离出来。
以下图所示,由于实际上HTML、CSS、JavaScript这些都逐渐静态化,因此再也不须要把它们放在应用服务器上了,咱们能够把它们放在专门的高性能静态服务器上,再进一步发展,就能够是CDN(Content Delivery Network,内容分发网络)。前端跟后端的通讯,基本都是经过AJAX来,也会有一些其余的好比WebSocket之类,总之尽可能少刷新了。
在这张图里面能够看到,真正的前端已经造成了,它跟应用服务器之间造成了自然的隔离,因此也可以很独立地进行一些发展演进。
如今不少Web程序在往SPA(单页面程序,Single Page Application)的方向发展,这类系统一般比较相似传统的C/S程序,交互过程比较复杂,所以它的开发过程也会遇到一些困难。
那为何你们要作SPA呢?它有不少明显的好处,最核心的优点就是高效。这个高效体如今两个方面:一是对于用户来讲,这种方式作出来的东西体验较好,相似传统桌面程序,对于那些须要频繁操做的行业用户,有很大优点。二是运行的效率较高,以前集成一些菜单功能,可能要用iframe的方式引入,但每一个iframe要独立引入一些公共文件,服务器文件传输的压力较大,还要初始化本身的一套内存环境,比较浪费,互相之间也不太方便通讯,通常要经过postMessage之类的方式去交互。
有了SPA以后,好比一块界面,就能够是一个HTML片断,用AJAX去加载过来处理以后放到界面上。若是有逻辑的JavaScript代码,也能够用require之类的异步加载机制去运行时加载,总体的思路是比较好的。
不少人说,就以这样的需求,用jQuery再加一个异步js加载框架,不是很足够了吗?这两个东西用得好的话,也是可以解决一些问题的,但它们处理的并非最关键的事情。在Web体系中,展示层是很自然的,由于就是HTML和CSS,若是只从文件隔离的角度,也能够作出一种划分的方式,逻辑放在单独的js文件里,html内部尽可能不写js,这就是以前比较主流的前端代码划分方式。
刚才咱们提到,SPA开发的过程当中会遇到一些困难,这些困难是由于复杂度大为提高,致使了一些问题,有人把这些困难归结为纯界面的复杂度,好比说,控件更复杂了之类,没有这么简单。问题在于什么呢?我打个比方:咱们在电脑上开两个资源管理器窗口,浏览到同一个目录,在一个目录里把某个文件删了,你猜猜另一个里面会不会刷新?
毫无疑问,也会刷新,可是你看看你用的Web页面,若是把整个复杂系统整合成单页的,能保证对一个数据的更新就实时反馈到全部用它的地方吗?怎么作,是否是很头疼?代码组织的复杂度大为提升,因此须要作一些架构方面的提高。
提到架构,咱们一般会往设计模式上想。在著名的《设计模式》一书中,刚开始就讲了一种典型的处理客户端开发的场景,那就是MVC。
传统的MVC理念咱们并不陌生,由于有Struts,因此在Web领域也有比较经典的MVC架构,这里面的V,就负责了整个前端的渲染,并且是服务端的渲染,也就是输出HTML。以下图所示:
在SPA时代,这已经不合适了,因此浏览器端造成了本身的MVC等层次,这里的V已经变成客户端渲染了,一般会使用一些客户端的HTML模版去实现,而模型和控制器,也相应地在浏览器端造成了。
咱们有不少这个层面的框架,好比Backbone,Knockout,Avalon,Angular等,采用了不一样的设计思想,有的是MVC,有的是MVP,有的是MVVM,各有其特色。
以Angular为例,它推荐使用双向绑定去实现视图和模型的关联,这么一来,若是不一样视图绑定在同一模型上,就解决了刚才所说的问题。而模型自己也经过某种机制,跟其余的逻辑模块进行协做。
这种方式就是依赖注入。依赖注入的核心理念就是经过配置来实例化所依赖的组件。使用这种模式来设计软件架构,会牺牲一些性能,在跟踪调试的便利性等方面也会有所损失,但换来的是无与伦比的松耦合和可替代性。
好比说,这些组件就能够单独测试,而后在用的时候随手引入,毫无压力。对于从事某一领域的企业来讲,光这一条就足以吸引他在上面大量投入,把全部不常变更领域模型的业务代码都用此类办法维护起来,这是一种财富。
若是咱们来设计Angular这么一个前端框架,应当如何入手呢?很显然,逻辑的控制必须使用JavaScript,一个框架,最本质的事情在于它的逻辑处理方式。
咱们的界面为何能够多姿多彩?由于有HTML和CSS,注意到这两种东西都是配置式的写法,参照后端的依赖注入,若是把这二者视为跟Spring框架中一些XML等同的配置文件,思路就豁然开朗了。
与后端不一样的是,充当前端逻辑工具的JavaScript不能作入口,必须挂在HTML里才能运行,因此出现了一个怪异的情况:逻辑要先挂在配置文件(HTML)上,先由另外的容器(浏览器或者Hybird的壳)把配置文件加载起来,而后才能从某个入口开始执行逻辑。好消息是,过了这一步,逻辑层就开始大放异彩了。
从这个时候开始,框架就启动了,它要作哪些事情呢?
这些是主线流程,还有一些支线,好比:
SPA的一个典型特征就是部分加载,界面的部件化也是其中比较重要的一环。界面片断在动态请求获得以后,借助模版引擎之类的技术,通过某种转换,放置到主界面相应的地方。因此,从这个角度来看,HTML的组件化很是容易理解,那就是界面的片断化和模板化。
JavaScript这个部分有好几个发展阶段。
JavaScript组件化的目标是什么呢,是清晰的职责,松耦合,便于单元测试和重复利用。这里的松耦合不只体如今js代码之间,也体如今js跟DOM之间的关系,因此像Angular这样的框架会有directive的概念,把DOM操做限制到这类代码中,其余任何js代码不操做DOM。
如上图所示,总的原则是先分层次,层内再做切分。这么作的话,再也不存在以前那种端到端组件了,使用起来没有原先那么方便,但在另外不少方面比较好。
这方面,业界也有不少探索,好比LESS,SASS,Stylus等。为何CSS也要作组件化呢?传统的CSS是一种扁平的文本结构,变动成本较高,好比说想要把结构从松散改紧凑,须要改动不少。若是把实际使用的CSS只看成输出结果,而另外有一种适合变动的方式看成中间过程,这就好多了。好比说,咱们把一些东西定义成变量,每一个细节元素使用这些变量,当须要总体变动的时候,只需修改这些变量而后从新生成一下就能够了。
以上,咱们讨论了大体的Web前端开发的组件化思路,后续将阐述组件化以后的协做过程和管控机制。