企业应用架构模式-30天阅读计划

构建计算机系统并不是易事。随着系统复杂性的增大,构建相应软件的难度将呈指数增大。前端

同其余行业同样,咱们只有在不断的学习中进步,从成功经验中学习,从失败教训中学习,才有望克服这些困难。程序员

这本书的内容就是这样一些“学习”经验。数据库

只有经过模式的总结和学习,才能更有效地与他人进行交流。浏览器

—选自《企业应用架构模式》性能优化

0.1 架构

软件业的人乐于作这样的事——找一些词汇,并把它们引伸到大量微妙而又互相矛盾的含义。一个最大的受害者就是“架构”(architecture)这个词。我我的对“架构”的感受是,它是一个让人印象深入的词,主要用来表示一些很是重要的东西。固然,我也会当心,不让这些对“系统结构”的“不恭之词”,影响到读者对本书的兴趣。服务器

不少人都试图给“架构”下定义,而这些定义自己却很难统一。可以统一的内容有两点:一点是“最高层次的系统分解”;另外一点是“系统中不易改变的决定”。愈来愈多的人发现:表述一个系统架构的方法不仅一种;一个系统中也可能有不少种不一样的架构,并且,对于什么在架构上意义重大的见解也会随着系统的生命周期变化。多线程

Ralph Johnson常常在邮件列表上发帖,并提出一些使人关注的看法。就在我完成本书初稿的同时,他又发表了一些关于“架构”的观点。他认为,架构是一种主观上的东西,是专家级项目开发人员对系统设计的一些可共享的理解。通常地,这种可共享的理解表现为系统中主要的组成部分以及这些组成间的交互关系。它还包括一些决定,开发者们但愿这些决定能及早作出,由于在开发者看来它们是难以改变的。架构的主观性也来源于此——若是你发现某些决定并不像你想象的那么难以改变,那么它就再也不与架构相关。到了最后,架构天然就浓缩成一些重要的东西,不论这些东西是什么。架构

在本书中,我提出一些本身的理解,涉及企业应用主要组成部分和我但愿能尽早作出的决定。在这些架构模式中,我最欣赏的就是“层次”,将在第1章中进行详细介绍。全书实际上就是关于如何将企业应用组织成不一样的层次,以及这些层次之间如何协同工做。大多数重要的企业应用都是按照某种形式的层次分层设计的;固然,在某些状况下,别的设计方式(如管道方式、过滤器方式等)也有它们本身的价值。在本书中咱们将不会讨论这些方式,而把注意力集中在层次方式上,由于它是应用最广的设计方式。数据库设计

本书中的一些模式毫无疑问是关于架构的,它们表示了企业应用各主要组成部分间的重要决定;另一些模式是关于设计的,有助于架构的实现。我没有刻意区分这两类模式,由于正如咱们前面讨论的,是否与架构相关每每带有主观性。工具

0.2 企业应用

编写计算机软件的人不少,咱们一般把这些活动都称为软件开发。可是软件的种类是不一样的,每种软件都有自身的挑战性和复杂性。我是在与几个从事电信软件开发的朋友交谈后,意识到这个问题的。企业应用在某些方面要比电信软件简单得多——多线程问题没有那么困难,无需关注硬件设备与软件的集成。可是,在某些方面,企业应用又比电信软件复杂得多——企业应用通常都涉及到大量复杂数据,并且必须处理不少“不合逻辑”的业务规则。虽然有些模式是适合全部软件的,可是大多数模式都还只适合某些特定的领域和分支。

个人工做主要是关于企业应用的,所以,这里所谈及的模式也都是关于企业应用的。(企业应用还有一些其余的说法,如“信息系统”或更早期的“数据处理”。)那么,这里的“企业应用”具体指的是什么呢?我没法给出一个精确的定义,可是我能够罗列一些我的的理解。

先举几个例子。企业应用包括工资单、患者记录、发货跟踪、成本分析、信誉评估、保险、供应链、记帐、客户服务以及外币交易等。企业应用不包括车辆加油、文字处理、电梯控制、化工厂控制器、电话交换机、操做系统、编译器以及电子游戏等。

企业应用通常都涉及到持久化数据。数据必须持久化是由于程序的屡次运行都须要用到它们——实际上,有些数据须要持久化若干年。在此期间,操做这些数据的程序每每会有不少变化。这些数据的生命周期每每比最初生成它们的那些硬件、操做系统和编译器还要长。在此期间,数据自己的结构通常也会被扩展,使得它在不影响已有信息的基础上,还能表示更多新信息。即便是有根本性的变化发生,或公司安装了一套全新的软件,这些数据也必须被“迁移”到这些全新的应用上。

企业应用通常都涉及到大量数据——一个中等规模的系统每每都包含1GB以上的数据,这些数据是以百万条记录的方式存在的。巨大的数据量致使数据的管理成为系统的主要工做。早期的系统使用的是索引文件系统,如IBM的VSAM和ISAM。现代的系统每每采用数据库,绝大多数是关系型数据库。数据库的设计和演化已使其自己成为新的技术领域。

企业应用通常还涉及到不少人同时访问数据。对于不少系统来讲,人数可能在100人如下,可是对于一些基于Web的系统,人数会呈指数级增加。要确保这些人都可以正确地访问数据,就必定会存在这样或那样的问题。即便人数没有那么多,要确保两我的在同时操做同一数据项时不出现错误,也是存在问题的。事务管理工具能够处理这个问题,可是它一般没法作到对应用开发者透明。

企业应用还涉及到大量操做数据的用户界面屏幕。有几百个用户界面是不足为奇的。用户使用频率的差别很大,他们也常常没什么技术背景。所以,为了避免同的使用目的,数据须要不少种表现形式。系统通常都有不少批处理过程,当专一于强调用户交互的用例时,这些批处理过程很容易被忽视。

企业应用不多独立存在,一般须要与散布在企业周围的其余企业应用集成。这些各式各样的系统是在不一样时期,采用不一样技术构建的,甚至连协做机制都不一样:COBOL数据文件、CORBA系统或是消息系统。企业常常但愿能用一种统一的通讯技术来集成全部系统。固然,每次这样的集成工做几乎都很难真正实现,全部留下来的就是一个个风格各异的集成环境。当商业用户须要同其业务伙伴进行应用集成时,状况就更糟糕。

即便是某个企业统一了集成技术,它们也仍是会遇到业务过程当中的差别以及数据中概念的不一致性。一个部分可能认为客户是当前签有协议的人;而另一个部门可能还要将那些之前有合同,但如今已经没有了的人计算在内。再有,一个部门可能只关心产品销售而不关心服务销售。粗看起来,这些问题彷佛容易解决,可是,一旦几百个记录中的每一个字段都有可能存在着细微差异,问题的规模就会造成不小的挑战——就算惟一知道这些字段之间差异的员工还在公司任职(固然,也许他在你察觉到以前就早已辞职不干了)。这样,数据就必须被不停地读取、合并、而后写成各类不一样语法和语义的格式。

再接下来的问题是由“业务逻辑”带来的。我认为“业务逻辑”这个词很滑稽,由于很难找出什么东西比“业务逻辑”更加没有逻辑。当咱们构建一个操做系统时,老是尽量地使得系统中的各类事物符合逻辑。而业务逻辑生来就是那样的,没有至关的行政努力,不要想改变它,固然,它们都有本身的理由。你必须面对不少奇怪的条件。并且这些条件相互做用的方式也很是怪异。好比,某个销售人员为了签下其客户几百万美圆的一张单,可能会在商务谈判中与对方达成协议,将该项目的年度到帐时间推迟两天,由于这样才能与该客户的帐务周期相吻合。成千上万的这类“一次特殊状况”最终致使了复杂的业务“无逻辑”,使得商业软件开发那么困难。在这种状况下,必须尽可能将这些业务逻辑组织成有效的方式,由于咱们能够肯定的是,这些“逻辑”必定会随着时间不断变化。

对于一些人来讲,“企业应用”这个词指的是大型系统。可是 须要注意的是,并非全部的企业应用都是大型的,尽管它们可能都为企业提供巨大的价值。不少人认为,因为小型系统的规模不大,能够不用太注意它们,并且在某种程度上,这种观点可以带来必定的成本节约。若是一个小型系统失败了,相对于大型系统的失败,这种失败就不会显得那么起眼了。可是,我认为这种思想没有对小型项目的累积做用给予足够的重视。试想,若是在小型项目上可以进行某些改善措施,那么一旦这些改善措施被成功运用于大型项目,它带来的效果就会很是大。实际上,最好是经过简化架构和过程,将一个大型项目简化成小型项目。

0.3 企业应用的种类

在咱们讨论如何设计企业应用以及使用哪些模式以前,明确这样一个观点是很是重要的,即企业应用是多种多样的,不一样的问题将致使不一样的处理方法。若是有人说“老是这样作” 的时候,就应该敲响警钟了。我认为,设计中最具挑战性(也是我最感兴趣)的地方就是了解有哪些候选的设计方法以及各类不一样设计方法之间的优劣比较。进行选择的控件很大,但我在这里只选三个方面。

考虑一个B2C(Business to Customer)的网上零售商:人们经过浏览器浏览,经过购物车购买商品。经过购物车购买商品。这样一个系统必须可以应付大量的客户,所以,其解决方案不但要考虑到资源利用的有效性,还要考虑到系统的可伸缩性,以便在用户规模增大时可以经过增长硬件的办法加以解决。该系统的业务逻辑能够很是简单:获取订单,进行简单的价格计算和发货计算,给出发货信息。咱们但愿任何人都可以访问该系统,所以用户界面能够选用通用的Web表现方式,以支持各类不一样的浏览器。数据源包括用来存放订单的数据库,还可能包括某种与库存系统的通讯交流,以便得到商品的可用性信息和发货信息。

再考虑一个租约合同自动处理系统。在某些方面,这样的系统比起前面介绍的B2C系统要简单,由于它的用户数不多(在特定时间内不会超过100个),可是它的业务逻辑却比较复杂。计算每一个租约的月供,处理如提前解约和延迟付款这样的事件,签定合同时验证各类数据,这些都是很是复杂的任务,由于租约领域的许多竞争都是以过去的交易为基础稍加变化而出现的。正是由于规则的随意性很大,才使得像这样一个复杂领域具备挑战性。

这样的系统在用户界面(UI)上也很复杂。这就要求HTML界面要能提供更丰富的功能和更复杂的屏幕,而这些要求每每是HTML界面目前没法达到的,须要更常规的胖客户界面。用户交互的复杂性还会带来事务行为的复杂性:签定租约可能要耗时1~2个小时,这期间用户要处于一个逻辑事务中。一个复杂的数据库设计方案中可能也会涉及到200多个表以及一些有关资产评估和计价的软件包。

第三个例子是一家小型公司使用的简单的“开支跟踪系统”。这个系统的用户不多,功能简单,经过HTML表现方式能够很容易实现,涉及的数据源表项也很少。尽管如此,开发这样的系统也不是没有挑战。一方面你必须快速地开发出它,另外一方面你又必须为它之后可能的发展考虑;也许之后会为它增长赔偿校验的功能,也许它会被集成到工资系统中,也许还要增长关于税务的功能,也许要为公司的CFO生成汇总报表,也许会被集成到一个航空订票Web Service中,等等。若是在这个系统的开发中,也试图使用前面两个例子中的一些架构,可能会影响开发进度。若是一个系统会带来业务效益(如全部的企业应用应该的那样),则系统进度延误一样也是开销。若是如今不作决策又有可能影响系统将来的发展。可是,若是如今就考虑了这些灵活性可是考虑不得当,额外的复杂性又可能会影响到系统的发展,进一步延误系统部署,减小系统的效益。虽然这类系统很小,可是一个企业中每每有不少这样的系统,这些系统的架构不良性累积起来,后果将会很是可怕。

这三个企业应用的例子都有难点,并且难点各不相同。固然,也不可能有一个适合于三者的通用架构。选择架构时,必须很清楚地了解面临的问题,在理解的基础上再来选择合适的设计。本书中也没有一个通用的解决方案。实际上,不少模式仅仅是一些可选方案罢了。即便你选择了某种模式,也须要进一步根据面临的问题来修改模式。在构建企业应用时,你不思考是不行的。全部书本知识只是给你提供信息,做为你作决定的基础。

模式是这样,工具也一样如此。在系统开发时应该选取尽量少的工具,同时也要注意,不一样的工具擅长处理的方面也不一样,切记不要用错了工具,不然只会事倍功半。

0.4 关于性能的考虑

不少架构的设计决策和性能有关。对于大多数与性能相关的问题,个人办法是首先创建系统,调试运行,而后经过基于测量的严格的优化过程来提升性能。可是,有一些架构上的决策对性能的影响,多是后期优化难以弥补的。并且即便这种影响能够在后期很容易地弥补,参与这个项目的人们任然会从一开始就担忧这些决策。

在这样的一本书中讨论性能一般很困难。这是由于“眼见为实”:全部那些关于性能的条条框框,不在你的具体系统中配置运行一下,是很难有说服力的。我也常常看到一些设计方案由于性能方面的考虑而被接受或拒绝,可是一旦有人在真实的设置环境中作一些测量,就会证实这些考虑是错误的。

本书将提出一些这方面的建议,包括尽可能减小远程调用(它在很长时间内都被认为是优化性能的好建议)。尽管如此,仍是建议读者在运用这些原则以前,在你的应用中具体试一试。一样,本书中的样例代码也有一些地方为了提升可读性而牺牲了效率。在你的系统中,须要自行决定是否进行优化。在作性能优化后,必定要与优化前进行测量对比,以肯定真的获得了优化,不然,你可能只是破坏了代码的可读性。

还有一个很重要的推论:配置上的重大变化会使得某些性能优化失效。所以,在升级虚拟机、硬件、数据库或其余东西到新的版本时,必须从新确认性能优化工做的有效性。不少状况下,配置变动都会对性能优化有影响,有时候你真的会发现,之前为了提高性能作的优化,在新环境下竟然影响性能。

关于性能的另外一个问题是不少术语的使用不一致。最明显的例子就是“可伸缩性”(scalability),它可能有6-7种含义。下面我使用其中一些术语。

响应时间是系统完成一次外部请求处理所须要的时间。这些外部请求多是用户交互行为,例如按下一个按钮,或是服务器API调用。

响应性不一样于请求处理,它是系统响应请求的速度有多快。这个指标在许多系统里很是重要,由于对于一些系统而言,若是其响应性太慢,用户将难以忍受——尽管其响应时间可能不慢。若是在请求处理期间,系统一直处于等待状态,则系统的响应性和响应时间是相同的。然而,若是可以在处理真正完成以前就给用户一些信息代表系统已经接到请求,则响应性就会好一些。例如,在文件拷贝过程当中,为用户提供一个“进度条”,将会提升用户界面的响应性,但并不会提升响应时间。

等待时间是得到系统任何形式响应的最小时间,即便应该作的工做并不存在。一般它是远程系统中的大问题。假设咱们让程序什么都不作,只是调用返回便可,则若是在本机上运行程序,通常都会当即获得响应。可是,若是在远程计算机上运行程序,状况就不同,每每须要数秒的时间才能获得响应。由于从发出请求到获得响应的数秒时间主要用于排除使信息在线路上传输的困难。做为应用开发者,我常常对等待时间无能为力。这也是为何要尽可能避免远程调用的缘由。

吞吐率是给定时间内可以处理多大的请求量。若是考察的是文件拷贝,则吞吐率能够用每秒字节量来表示。对于企业应用来讲,吞吐率一般用每秒事务数(tps)来度量。这种方法的一个问题是指标依赖于事务的复杂程度。对于特定系统的测试,应该选取普通的事务集合。

在这里,性能或指吞吐率,或者指响应时间,由用户本身决定。当经过某种优化技术后,使得系统的吞吐率提升了,可是响应时间降低了,这时就很差说系统的性能提升了,最好用更准确的术语表示。从用户角度而言,响应性每每比响应时间更重要,所以,为了提升响应性而损失一些响应时间或者吞吐率是值得的。

负载是关于系统当前负荷的表述,也许能够用当前有多少用户与系统相连来表示。负载有时也做为其余指标(如响应时间)的背景。所以,咱们能够说:在10个用户的状况下,请求响应时间是0.5秒,在20个用户的状况下,请求响应时间是2秒。

负载敏感度是指响应时间随负载变化的程度。假设:系统A在10~20个用户的状况下,请求响应时间都是0.5秒;系统B在10个用户的状况下,请求响应时间是0.2秒,在20个用户的状况下,请求响应时间上升到2秒。此时,系统A的负载敏感度比系统B低;咱们还可使用术语衰减(degradation),称系统B衰减得比系统A快。

效率是性能除以资源。若是一个双CPU系统的性能是30tps,另外一个系统有4个一样的CPU,性能是40tps,则前者效率高于后者。

系统的容量是指最大有效负载或吞吐率的指标。它能够是一个绝对最大值或性能衰减至低于一个可接受的阈值以前的临界点。

可伸缩性度量的是向系统中增长资源(一般是硬件)对系统性能的影响。一个可伸缩性的系统容许在增长了硬件后,可以有性能上的合理提升。例如,为了使吞吐率提升一倍,要增长多少服务器等。垂直可伸缩性或称垂直延展,一般指提升单个服务器的性能,例如增长内存。水平可伸缩性或称水平延展,一般指增长服务器的数目。

问题是,设计决策对全部性能指标的做用并不相同。好比,某个服务器上运行着两个软件系统:Swordfish的容量是20tps,而Camel的容量是40tps。哪个的性能更高?哪个的可伸缩性好?仅凭这些数据,咱们没法回答关于可伸缩性的问题,咱们只能说Camel系统在单片机上的效率更高。假设又增长了一台服务器后,咱们发现:Swordfish的容量是35tps,Camel的容量是50tps。尽管Camel的容量仍然大于Swordfish,可是后者在可伸缩性上却显得比前者更好。假设咱们继续增长服务器数目后发现:Swordfish每增长一台服务器提升15tps,Camel每增长一台服务器提升10tps。在得到了这些数据后,咱们才能够说,Swordfish的水平可伸缩性比Camel好,尽管Camel在5个服务器如下会有更好的效率。

当构建企业应用系统时,关注硬件的可伸缩性每每比关注容量或效率更重要。若是须要,可伸缩性能够给予你得到更好性能的选择,可伸缩性也能够更容易实现。有时,设计人员费了九牛二虎之力才提升了少量容量,其开销还不如多买一些硬件。换句话说,假设Camel的费用比Swordfish高,高出的部分正好能够买几台服务器,那么选择Swordfish可能更合算,尽管你目前只须要40tps。如今人们常常抱怨软件对硬件的依赖性愈来愈大,有时为了运行某些软件就不得不对硬件进行升级,就像我同样,为了用最新版本的Word,就必须不断地升级笔记本电脑。可是总的来讲,购买新硬件仍是比修改旧软件来得便宜。一样,增长更多的服务器也比增长更多的程序员来得便宜——只要你的系统有足够的可伸缩性。

0.5 模式

模式的概念早就有了。我在这里不想把这段历史从新演绎一遍。只是想简单谈谈我对模式和它们为何是描述设计的重要手段的一些见解。

模式没有统一的定义。可能最好的起点是Christopher Alexander给出的定义(这也是许多模式狂热者的灵感来源):“每个模式描述了一个在咱们周围不断重复发生的问题以及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而没必要作重复劳动”[Alexander et al.]。尽管Alexander是建筑家,他谈论的是建筑模式,但其定义也能很好地适用于软件业。模式的核心就是特定的解决方案,它有效并且有足够的通用性,能解决重复出现的问题,模式的另外一种视角是把它当作一组建议,而创造模式的艺术则是将不少建议分解开来,造成相互独立的组,在此基础上能够相对独立地讨论它们。

模式的关键点是它们源于实践。必须观察人们的工做过程,发现其中好的设计,并找出“这些解决方案的核心”。这并非一个简单的过程,可是一旦发现了某个模式,他将是很是有价值的。对于我来讲,价值之一是可以撰写这样一本参考书。你没必要通读本书的所有内容,也没必要通读全部有关于模式的书。你只须要了解到这些模式都是干什么的,它们解决什么问题,它们是如何解决问题的,就足够了。这样,一旦碰到相似问题,就能够从书中找出相应的模式。那时,再深刻了解相应的模式也不迟。

一旦须要使用模式,就必须知道如何将它运用于当前的问题。使用模式的关键之一是不能盲目使用,这也是模式工具为何都那么惨的缘由。我认为模式是一种“半生不熟品”,为了用好它,还必须在本身的项目中把剩下的那一半“火候”补上。我本人每次在使用模式时,都会东改一点西改一点。所以你会屡次看到同一解决方案,但没有一次是彻底相同的。

每一个模式相对独立,但又不彼此孤立。有时候它们相互影响,如影随形。例如,若是在设计中使用了领域模型,那么常常还会用到类表继承。模式的边界原本也是模糊的,我在本书中也尽可能让它们各自独立。若是有人说“使用工做单元”,你就能够直接去看工做单元这个模式如何使用,而没必要阅读全书。

若是你是一个有经验的企业应用设计师,也许会对大多数模式都很熟悉。但愿本书不会给你带来太大的失望。(实际上我在前言里面已经提醒过了。)模式不是什么新鲜概念。所以,撰写模式书籍的做者们也不会声称咱们“发明”了某某模式,而是说咱们“发现”了某某模式。咱们的职责是记录通用的解决方案,找出其核心,并把最终的模式记录下来。对于一个高级设计师,模式的价值并不在于它给予你一些新东西,而在于它能帮助你更好地交流。若是你和你的同事都明白什么是远程外观,你就能够这样很是简洁地交流大量信息:“这个类是一个远程外观模式。”也能够对新人说:“用数据传输对象模式来解决这个问题。”他们就能够查找本书来搞清楚如何作。模式为设计提供了一套词汇,这也是为何模式的名字这么重要的缘由。

本书的大多数模式是用来解决企业应用的,基本模式一章(见第18章)则更通用一些。我把它们包含进来的缘由是:在前面的讨论中,我引用了这些通用的模式。

0.5.1 模式的结构

每一个做者都必须选择表达模式的形式。一些人采用的表达基于模式的一些经典教材如[Alexander et al.]、[Gang of Four]或[POSA]。另外一些人用他们本身的方式。我在这个问题上也斟酌了好久。一方面我不想象GOF同样太精炼,另外一方面我还要引用他们的东西。这就造成了本书的模式结构。

第一部分是模式的名字。模式名很是重要,由于模式的目的之一就是为设计者们交流提供一组词汇。所以,若是我告诉你Web服务器是用前端控制器和转换试图构建的,而你又了解这些模式,那么你对个人Web服务器的架构就会很是清楚了。

接下来的两部分是相关的:意图和概要。意图用一两句话总结模式;概要是模式的一种可视化表示,一般是(但不老是)一个UML图。这主要是想给模式一个简单的概况,以帮助记忆。若是你对模式已经“心知肚明”,只是不知道它的名字,那么模式的意图和概要这两部分就能为你提供足够的信息。

接下来的部分描述了模式的动机。这可能不是该模式所能解决的惟一问题,但倒是我认为最具表明性的问题。

“运行机制”部分描述了解决方案。在这一部分,我会讨论一些实现问题以及我遇到的变化状况。我会尽量独立于平台来讨论——也有一个部分是针对平台来讨论的,若是不感兴趣能够跳过这部分。为了便于解释,我用了一些UML图来辅助说明。

“使用动机”部分描述了模式什么时候被使用。这部分讨论是使我选择该模式而不是其余模式的权衡考虑。本书中不少模式均可以相互替代,例如页面控制器和前端控制器能够相互替代。不多有什么模式是非它不可的。所以,每当我选择了一种模式以后,我老是问本身“你何时不用它?”这个问题也常常驱使我选择其余方案。

“进一步阅读”部分给出了与该模式相关的其余读物。它并不完善。我只选择我认为有助于理解模式的参考文献,因此我去掉了对本书内容没有价值的任何讨论,固然其中也可能会遗漏一些我不知道的模式。我也没有提到一些我认为可能读者没法找到的参考文献,再就是一些不太稳定的Web连接。

我喜欢为模式增长一个或几个例子。每一个例子都很是简单,它们是用Java语言或C#语言编写的。我之因此选择两种语言,是由于它们多是目前绝大多数专业程序员都能读懂的语言。必须注意,例子自己不是模式。当你使用模式时,不要想固然地认为它会和例子同样,也不要把例子当作某种形式的宏替换。我把例子编得尽可能简单以突出其中模式相关的部分。固然,省略的部分并非不重要,只是它们通常都特定于具体环境,这也是为何模式在使用时通常都必须作适当调整的缘由。

为了尽可能使例子简单可是又可以突出核心意思,我主要选择那些简单而又明确的例子,而不是那些来自于系统中的复杂例子。固然,在简单和过度之间掌握平衡是不容易的,可是咱们必须记住:过度强调具体应用环境反而会增长模式的复杂性,使得模式的核心内容不易理解。

这就是为何我在选择例子时选取的是一些相互独立的例子而不是相互关联的例子的缘由。独立的例子有助于对模式的理解。可是在如何将这些模式联合在一块儿使用上却支持很少。相互关联的例子则相反,它体现了模式间是如何相互做用的,可是对其中每一个模式的理解却依赖于对其余全部模式的理解。理论上,是能够构造出既相互关联又相互独立的例子,但这是一项很是艰巨的工做——至少对于我来讲是这样。所以,我选择了相互独立的例子。

例子中的代码自己也主要用来加强对思想的理解。所以,在其余一些方面考虑可能不够——特别是错误处理,在这方面,我没有花费不少笔墨,由于到目前为止,我尚未得出错误处理方面的模式。在此,那些代码纯粹用来讲明模式,而并非用来显示如何对任何特定的业务问题进行建模。

正是因为这些缘由,我没有把这些代码放到个人网站上供你们下载。为了让那些基本的思想在应用设置下有所意义,本书的每一个样例代码都充满着太多的“脚手架”来简化它们。

并非每一个模式中都包含上面所述的各个部分。若是我不能想出很好的例子或动机等内容,我就会把相应部分省略。

0.5.2 模式的局限性

正如我在前言中所述,对于企业应用开发而言,本书介绍的模式并不全面。我对本书的要求,不在于它是否全面,而在于它是否有用。模式这个领域太大了,单凭一我的的头脑是没法作到面面俱到的,更不用说是一本书了。

本书中所列的模式都是我在具体领域中遇到的,但这并不代表我已经理解了每个模式以及它们之间的关系。本书的内容只是反映了我在写书时的理解,在编写本书的过程当中,我对相关内容的理解也不断发展和加深,固然,在本书发表以后,我仍然但愿本人对模式的理解还可以继续发展。对于软件开发而言,有一点是能够确定的,那是软件开发永远不会中止。

当你使用模式时请记住:它们只是开始,而不是结束。任何做者去囊括项目开发中的全部变化和技术是不可能的。我编写本书的目的也只是做为一个开始,但愿它可以把我本身的和我所了解的经验和教训传递给读者,大家能够在此基础上继续努力。请你们记住:全部模式都是不完备的,大家都有责任在本身的系统中完善它们,大家也会在这个过程当中获得乐趣。

——选自:《企业应用架构模式》 [Patterns of Enterprise Application Architecture] [英] 福勒 著;王怀民,周斌 译

相关文章
相关标签/搜索