精华内容
下载资源
问答
  • 企业应用系统架构设计模式,企业应用系统架构设计模式
  • 微软 PPT详细讲解:企业应用系统架构设计模式 企业应用系统架构介绍,设计使用者界面元件与设计模式等。
  • Microsoft+.NET企业应用架构设计

    热门讨论 2012-02-20 17:54:59
    《Microsoft .NET企业应用架构设计》由两位企业级系统开发专家执笔,会告诉你如何用各种模式和技术来控制项目的复杂性,让系统更易于编写、维护和升级。  读者会得到实用的架构方面的指导,包括:  ·在早期设计...
  • 微服务好像是这两年突然火起来的,其实和很多其他架构风格一样,微服务架构也是我们在用软件改变世界的过程中,为了适应内外部环境的变化,而逐渐演化出的一种当前的最佳实践。 比如SOA,比如J2EE,比如传统分布式;...

    这个话题曾经分别在PWorld大会和QCon2016大会上做过分享,得到不错的反响,今天终于有时间整理到博客上了。

    微服务好像是这两年突然火起来的,其实和很多其他架构风格一样,微服务架构也是我们在用软件改变世界的过程中,为了适应内外部环境的变化,而逐渐演化出的一种当前的最佳实践。
    比如SOA,比如J2EE,比如传统分布式;微服务架构和它们都有千丝万缕的联系。

    这里写图片描述


    范式一、采用同步方式记录业务流水

    这里写图片描述

    流水记录了业务状态最终确定前的整个过程,是给业务参与各方看的,这个参与各方包括了客户(比如大家拿到的信用卡刷卡记录)、第三方系统(比如对账文件)、内部用户(比如我们给客服打电话,客服可以知道你的交易历史)等等。

    由于流水的作用和系统日志非常像,因此有些系统在设计时会把这两者混淆起来,基于性能的考虑,会像记录日志那样,用异步方式来记录流水。其实这是非常大的误区。就像上面所说,流水有业务含义,是给业务参与各方看的,它所记录的数据应该是和业务数据有一致性要求,而日志是给我们程序员看的,偶尔丢个一两条是可接受的。

    因此我们需要用同步的方式来记录业务流水,也就是说记录流水应该和正常的业务操作在同一个事务中。

    上图中,第一个“内部操作”更改了业务数据状态,因此需要同步记录业务流水,其他几个环节只记录日志即可。


    范式二、流水号设计的GAIR模式

    在记录流水和日志的过程中,我们需要唯一标识一笔服务调用。站在IT全局的视角来看,我们需要记录并能在适当的时候还原整个调用链。出现数据不一致时,我们要进行补偿操作,又需要能够定位错误发生时的数据状态……

    这些都需要以“流水号”为基础,这就带来了微服务架构的第二个范式——流水号的GAIR(盖尔)模式
    这里写图片描述

    G、A、I、R分别代表:Global_ID(全局流水号)、Answer_ID(响应流水号)、InRequest_ID(外部请求流水号)、Request_ID(内部请求流水号)

    这四个流水号的产生方、产生时机各不相同,下图展示了它们之间的区别和联系。
    这里写图片描述


    范式三、元数据驱动的微服务定义

    这里写图片描述

    以元数据的方式定义微服务带来两个好处。

    一、机器可读,这给未来全面自动化提供了前提条件。
    二、标准统一,这给服务在整个交付环节中的横向打通提供了支撑。

    这里写图片描述

    我们在实践中,以元数据方式,定义了服务接口数据的结构、每个数据项所遵循的数据标准、每个服务接收请求数据时的校验规则和值转换规则等等。

    这些元数据提供给专门的服务治理系统、数据治理系统、DevOps平台,从而构建出数字化IT。


    范式四、同步模式异步化

    在移动互联的外部环境中,微服务化的IT系统如何应对不确定的并发请求、超量请求?同时还要兼顾我们所连接的外部系统的网络中断、宕机等服务不可用、超时等一系列问题。

    这里写图片描述

    要解决这些问题,需要运用我们的第四个范式:以异步的方式处理同步调用。
    在实践中,我们所使用的异步方式和传统异步不太一样。

    这里写图片描述

    传统基于事件的异步,每个并发流作为一个有限状态机,应用直接控制并发,随着负载的增加,吞吐量会饱和,响应时间也会线性增长。

    这里写图片描述

    我们使用SEDA(Staged Event Driven Architecture),将接入、接出与逻辑处理相隔离,根据不同的业务操作类型合理分组,分别对待。


    范式五、进程间服务无状态

    什么是状态?首先,我们这里所说的状态是一种数据。如果一个数据需要在多个服务之间共享才能完成一笔交易,那么这个数据就被称为状态。

    依赖这个状态的服务,就是有状态服务。否则,就是无状态服务。

    这里写图片描述

    在业务上,状态的共享是不可避免的。典型的用户Session、现在新出现的云粘贴、网约车都是需要状态在不同服务间共享的场景。

    但在技术实现上,考虑到系统的可伸缩性,我们又需要做到无状态化处理。
    具体有四种手段:
    一、请求方持有状态,每次调用时传递给服务提供方
    二、粘滞+复制,这种技术并不新鲜,传统的JavaEE应用服务器集群就采用这种方式。这种方式对应用来说简单有效,但需要中间件支持。

    后面两种手段类似,都可以称为状态共享
    一种是,把状态保存在分布式缓存中
    另一种,把状态保存在持久化数据库中
    区别也显而易见,在此不做赘述。

    这里写图片描述

    具体使用哪种方式,要从多个维度综合考量,这里列出了我们经常考量的几个维度:时间窗口、性能、可靠性、安全性。


    范式六、保证最终数据一致性

    接下来是微服务架构下的数据一致性问题。这是一个大课题,概括的讲,我们可能需要转变思路,考虑采用柔性事务,使得数据达到最终一致。

    这里写图片描述

    当然,有些场景是必须要追求强一致性的,那么我们可能要在设计服务时就要考虑,是不是可以不分布。毕竟,“低耦合”是美好的,但同时还要有“高内聚”。

    这里写图片描述

    保证数据最终一致性有三种模式:
    1、可靠事件模式
    2、补偿模式
    3、TCC模式


    范式七、用编排实现微服务组合

    前面讲了这些模式,从架构角度来看挺清楚,确实也应该这么做。但是从工程角度来看,实施起来难度其实也不小。微服务之间的调用超时、事务、异步、状态等等,要做到代码写好,不出错,恐怕也是一个门槛比较高的事情。

    所以,我们强调:用编排方式实现微服务的组合。
    无论是配置式的编排:
    这里写图片描述

    还是图形式的编排:
    这里写图片描述

    都可以大大降低编程复杂度,使得一些很好的架构思想不会因为工程实现上的复杂和高门槛,而难以落地,最终成为空谈。

    如果大家对编排方式实现微服务的组合没有直观的感觉,推荐大家访问:ifttt.com,一试便知。


    范式八、业务配置集中管理

    最后一个范式是:业务配置集中管理

    记得前两天有位群友问我,docker启动时,如何根据不同的参数动态加载面向测试、生产环境的配置。
    这个问题的答案就是业务配置集中管理。

    其实技术上,业务配置集中管理没有什么太多的难点。我们需要做的是有一个切实可行的步骤来逐步实现。

    这里写图片描述


    总结

    这些八个范式当然没有涵盖微服务架构中的所有方面,希望能够在以后的实践中总结出更多的经验,可以分享给大家。

    展开全文
  • 基本设计原则 写出可以正常工作的代码是一回事,写出可以正常工作的良好代码则是另外一回事。一个设计精良的系统并不是一系列指令和修补的堆砌,里面还有很多与设计直接或间接相关的东西。与国际化标准中定义的其他...

    基本设计原则

    写出可以正常工作的代码是一回事,写出可以正常工作的良好代码则是另外一回事。一个设计精良的系统并不是一系列指令和修补的堆砌,里面还有很多与设计直接或间接相关的东西。与国际化标准中定义的其他质量特性相比,需要更加重视代码的可维护性,之所以选择这个特性,并不是因为其他特性(例如可扩展性、可伸缩性)和可维护性相比不重要,而是保持代码的可维护性的代价比较高,而且容易让开发者忽视,可维护是系统最关键的问题。

    对于可维护性分为两点解析。结构化设计是第一要素,这可以通过一系列的编码技术来保证。代码的可读性是另外一个重要因素,若代码附带了很多内部文档以及适当的变化跟踪系统,那么也不难实现。实际上一个完美系统只会出现在完美的世界中。

    对于较差的设计还有需求的不完备。所以很自然的,敏捷开发是提高交流,完备需求最好的方法,敏捷方法可以带来团队内部以及团队和客户之间的持续交流。但是,你也应该小心,敏捷开发方法也会不自觉的增加开发成本,并造成需求的不断增加。在敏捷的过程中,你必须保证流程中的每个人都能理解这么做的原因,项目干系人不了解角色和不配合,或不能在迭代之间总结,敏捷方法是不会成功的。

    在设计的过程中,避免把软件设计的过于坚硬。所谓坚硬,就是指对那些修改有较大的抵触的软件。抵触是通过复原能力来衡量的,若某个模块进行了修改,这又引发了你不得不对其依赖模块的修改,就很难预料某个修改所带来的代价。很多时候,我们对于Bug都只是临时的修改,通常而言临时的修改并不会比彻底的解决快速很多,临时的修补也不会给整个设计带来太多难以纠正的不良影响。不过积少成多,这就成了一个不好的信号。这样的设计通常叫高粘度,高粘度不是一件好事,因为意味着软件难以修改,就像黏度高的液体不容易流动。

    结构化设计

    结构化设计从理念诞生开始,内部隐藏的结构化设计核心原则一直是今天的指导思想,高内聚和低耦合这两个原则在面向对象世界风光无限。内聚的衡量标准从低至高,内聚越高越说明软件设计的越好。高内聚的模块意味着可维护性和可重用性,因为这些模块的外部依赖很少。低内聚的模块容易在其他模块留下依赖,让软件变得顽固坚硬且高粘度。耦合的衡量标准从低到高,耦合越低说明软件设计得越好。高内聚和低耦合唇齿相依,若系统满足了这两个条件,那么通常来说该系统已经基本满足了高可读性,高可维护性,易于测试和易于重用的要求。

    分离关注点

    我们在设计系统需要考虑内聚和耦合两个因素的时候,分离关注点有助于我们实现这个目标。分离关注点的核心在于将系统拆分成各不相同且最好没有重叠的功能,分离关注点原则建议我们一次只处理一个关注点。这并不代表此时要将所有的其他关注点都抛在脑后,而是说当你决定用某个模块来实现这个关注点之后,只需要全神贯注于实现该模块即可。从这个角度考虑,其他关注点都是不相关的。具体来说,分离关注点是通过模块化代码以及大量运用信息隐藏来实现。模块化编程鼓励我们使用不同的模块来实现不同的功能。模块拥有自己的公开接口,可以和其他模块通信,模块同时也包含大量的内部信息,供自身使用。信息隐藏是一条通用的设计选择,固定的公开接口隐藏软件模块的实现细节,以降低未来修改造成的影响。

    其实分离关注点第一种支持的编程理念是过程式编程,在过程式编程中,分离关注点依靠函数和过程来实现。不过分离关注点的概念不仅限于编程语言,它超越了纯粹编程的领域,还应用到了软件架构的很多方面。在面向服务架构SOA中,服务用来表示关注点。分层架构也基于分离关注点的原则构造。

    面向对象设计

    面向对象的设计可以说是一座里程碑,面向对象设计中的一个重要的步骤就是为问题领域找到一个干净灵活的抽象。若要很好的完成这一步,那么应该考虑的是事情而不是流程。应该关注的于“什么”而不是“如何”。

    可重用性是面向对象理念中一个非常重要的方面,也是面向对象广泛使用的根本原因。《设计模式》一书作者总结出了两种实现重用的方式:白盒重用和黑盒重用。前者基于继承,后者基于对象组合。在实际设计中,尽量使用对象组合,而不是类型继承。在现实世界项目中,对象组合更加安全,易于维护和测试,在组合中,修改组合对象并不会影响到内部对象。

    除了组合之外,另一种方法也常用来与类型继承比较,就是聚合。组合和聚合之间的区别在于,组合关系中容器和内部类存在静态关联,销毁了容器内部类也会被销毁。而在聚合中,二者关联较弱,即使容器销毁,关键类仍可以使用。

    高级原则

    在最近几年,上面提到的内聚、低耦、分离关注点等原则有了进一步的演化和增强。下面列举出3条高级原则。

    开放封闭原则。能帮助软件中的单元(包括类型、函数或模块)更容易适应变化。每次发生变化时,要通过添加新代码来增强现有类型的行为,而不是修改原有的代码。当前这个原则最好的方式是提供一个固定的接口,然后让可能发生变化的类实现该接口。随后调用者基于该接口操作。

    里氏替换原则。当某个类型派生于某个现有类型时,派生类应该能够用于任何可以使用父类的地方,这就是多态。开放封闭原则和里氏替换原则有紧密的关系,任何使用了违反里氏替换原则的类型的方法都无法满足开放封闭原则。

    依赖倒置原则。原则名中的"倒置"表示在实现过程中应采用自顶向下的方式,且应该关注于高层次此模块的工作流,而不是低层次的模块具体的实现。从这点考虑,低层次模块可以直接插入到高层次模块中。

    从原则到模式

    从高处着眼,业界普遍认同的两种软件模式:设计模式和架构模式。在设计、编码时,我们会使用设计模式。而在概括的规划系统的整体设计时,我们会使用架构模式。还有一个值得介绍的模式是重构模式,常见的重构模式包括“抽取接口”和“封装字段”等。

      他们每个模式都描述了一个问题,这个问题在我们的环境中一遍一遍的出现。且模式还给出了这个问题的核心解决方案,这个方案一次次的重用,而无需每次重头开始。一种设计模式就是一个一直且被广泛关注的核心解决方案,适用于解决一类实现过程中可能出现的专门的问题。

    但是设计模式不是万能的,不能教条的使用。设计模式也不是超人,不能拯救一个陷入泥潭的项目。设计模式也许会伴你左右,但并不会给你带来额外的能力。设计模式只不过是种有用的东西,仅此而已。使用设计模式最常见的错误是逐一查看每条模式,然后生搬硬套的应用到某个问题上。相反,模式应该反过来使用,针对现有问题,尝试选择一种来解决。使用设计模式并不能在本质上让你的解决方案更有价值,真正的价值在于,在交付的时候你的解决方案是否能正常工作并满足需求。

    在得到完整解决方案的过程中,对设计原则的系统化应用会让你或早或晚的来到某个已知的设计模式身边。之所以如此确定,是因为模式就是其他人已经遇到过并加以分类的问题的解决方案。模式并不能为解决方案增加价值,价值在于为架构师或者开发者提供解决方案。

    反模式

    在物理学中有物质和反物质之分,类似地,在软件中我们用模式组成解决方案,用反模式来组成反解决方案。两者区别在于,模式能让我们得到好的解决方案,反模式则带来不好的解决方案。反模式是一种介绍如何从问题演化到不好的解决方案的模式。反模式的基本原则在于,这些刚开始模式看上去像个不错的设计,能为你的类型添加新的功能或提高效率。而实际上,反模式会让你逐渐走入歧途,带来的麻烦远比好处要多。

    设计者和反模式在某种程度上会互相吸引,不过老练的设计者会认出这糖衣炮弹并尽力避免。反模式有很多,下面列举两个。

    “将架构作为需求”反模式是指,设计团队中的某个具有影响力的成员执意在项目中使用某个不成熟的技术或者产品,即使尚没有证据表明其作用或其是否适用于上下文。

    “将发布作为测试”反模式是指,软件产品发布时并没有太过考虑那些无聊耗时的单元测试或集成测试。用户是产品的最终使用者,因此软件质量就由他们来把关吧。

    安全性作为需求

    重视安全性是一个远比你想象中更复杂的过程。若工程师不了解基本的安全原则、常见的安全缺陷、基本的安全设计或者安全性测试,那么他们绝对没有可能写出安全的软件。安全性必须从一开始就小心把握,安全的设计始于架构,而不是以后可以补充的东西。安全是由设计决定的,若想处理好安全性问题,应该选用一种关注安全性的开发方法,从而让你在设计系统的时候也时刻牢记安全性。

    SDL,安全开发生命周期是微软公司内部使用的一种通过减少安全Bug,从而提高软件安全性的开发流程。SDL实际上是一个迭代的过程,关注于软件过程中的安全方面。 SDL的基石分为3层:分层、组件化和角色。例如,分层会给数据服务器带来好处,将安全性检查放在业务层,让唯一用户数据层访问数据库,在业务组件中使用代码访问安全来阻止非信任代码执行的需要权限的操作。组件化意味着区分需要安全保护的组件,并不代表逻辑上的架构分成一个程序集,对于每个组件,我们都需要确定他们正常运行的最小权限集合。角色是指派给用户一个逻辑属性,角色代表用户在应用程序上下文中的位置,在基于角色的安全模型中,使用伪装用户或委托执行造成的风险可被有效的降低。

    一般情况下,我们需要建立一个威胁模型来简化风险。威胁模型一般包含从多个角度检查组件所受的威胁,STRIDE就是威胁模型的实践,其中包含六种类型的威胁。用户身份欺诈;篡改;抵赖;信息泄露;拒绝服务;权限提升。

    总的来说,若具体的实现不够强壮安全,那么内建了安全性考虑的设计、良好的安全威胁模型的风险分析就都没有任何意义。

    从对象到方面

    面向对象理念擅长于将系统分解成组件并且用组件来描述流程,也擅长于处理组件的关注点。不过那些横切的关注点,面向对象却不行。横切关注点是指那些会影响系统多个组件的关注点,例如日志、安全、异常处理等。AOP面向方面主要目的是将横切关注点与核心关注点的实现拆分开。具体面向方面不做太多描述。

    相关博客:


    展开全文
  •  《.net应用架构设计:原则、模式与实践》一共分为三个部分:第一部分首先介绍了企业应用架构与设计的流程和核心概念,然后讲解了应用架构中常用的设计模式和设计原则,以及常用的几种设计方法;第二部分的主题是...
  • 本书先介绍了一些企业应用开发的基础知识,比如分层架构、WEB表现、业务逻辑、数据库映射、并发、会话、分布策略等等。通过使用场景、解决方案、UML等手段详细介绍了设计模式(包括一些常用的设计模式GOF23和本书上...

     

    本书先介绍了一些企业应用开发的基础知识,比如分层架构、WEB表现、业务逻辑、数据库映射、并发、会话、分布策略等等。通过使用场景、解决方案、UML等手段详细介绍了设计模式(包括一些常用的设计模式GOF23和本书上新创的设计模式)。了解书中这些模式是干什么的、它们解决什么问题、它们是如何解决问题的。这样,如果你碰到类似的问题,就可以从书中找到相应的模式。可以为你节约成本、缩短项目周期时间、避免风险,以确保项目能够完美的完成。

     

    一、三个基本层次:表现层、领域层、数据源层

    层次

    职责

    表现层

    提供服务,显示信息(例如在WindowsHTML页面中,处理用户请求(鼠标点击、键盘敲击等),HTTP请求,命令行调用,批处理API

    领域层

    逻辑,系统中真正的核心

    数据源层

    与数据库,消息系统、事务管理器及其他软件包通信

    关于依赖性的普遍性原则:领域层和数据源层绝对不要依赖于表现层。

    一旦选择了处理节点,接下来就应该尽可能使所有代码保持在单一进程内完成(可能是在同一个节点上,也可能拷贝在集群中的多个节点上)。除非不得已,否则不要把层次放在多个进程中完成。因为那样做不但损失性能,而且增加复杂性,因为必须增加类似下面的模式,如远程外观和数据传输对象。

    复杂性增压器:分布、显式多线程、范型差异、多平台开发以及极限性能要求(如每秒100个事务以上)。

     

    二、领域逻辑

    领域逻辑的组织可以分成三种主要模式:事务脚本、领域模型、表模块。

    三者之间的区别:

    事务脚本是一个过程来控制一系列动作逻辑的执行。

    领域模型不再是由一个过程来控制用户某动作的逻辑,而是由每一个对象都承担一部分相关逻辑。这些对象可以看成是领域的不同组成部分。

    表模块只有一个公共的合同类实例,而领域模型对数据库中每一个合同都有一个相应的合同类的实例。

     

     

    三、映射到关系数据库

    在使用领域模型的时候,它的读取应该把相关联的对象也一块读出来。例如,读取一个合同,应该把合同涉及到的产品和定购厂商的对象加载到内存中。由时候为了避免这些没有必要的连带读取,我们可以使用【延迟加载】模型。

    读取数据的时候,性能问题可能回变得比较突出。这就导致了几条经验法则。

    1)、尽可能一次查询多个记录,不要一次查询一个记录,然后进行多次查询。可以一次查询多条相关的记录,例如使用联合查询。或者使用多条SQL语句。

    2)避免多次进入数据库的方法是使用连接(Join),这样就可以通过一次返回多个表。可以制作一个入口,让入口完成相关数据的一次性读取。

    3)数据库中进行优化。DBA来优化数据库。

    映射到关系数据库的时候,一般会遇到三种情况:

    1)  自己选择数据库方案。

    2)  不得不映射到一个现有数据库方案,这个方案不能改变。

    3)  不得不映射到一个现有数据库方案,但这个方案是可以考虑改变的。

    最简单的情况是自己选择数据库方案,并且不用迁就领域逻辑的复杂性。当已经存在一个数据库方案的时候,应该逐步建立领域模型并包括数据映射器,把数据保存到现有的数据库中。

     

    四、并发

    并发问题:更新丢失和不一致读。

    并发问题,人们提出了各种不同的解决方案。对于企业应用来说,有两个非常重要的解决方案:一个是隔离,一个是不变性。

    隔离是划分数据,使得每一片数据都可能被一个执行单元访问。比如文件锁。

    不变性是识别那些不变的数据,不用总考虑这些数据的并发问题而是广泛地共享它们。

    当有一些可变数据无法隔离的时候,会发生什么样的情况呢?总的来说,我们可以使用两种形式的并发控制策略:乐观并发控制和悲观并发控制。

    如果把乐观锁看作是关于冲突检测的,那么悲观锁就是关于冲突避免的。

    假如MartinDavid同时都要编辑Customer文件。如果使用乐观锁策略,他们两个人都能得到一份文件的拷贝,并且可以自由编辑文件。假设David第一个完成了工作,那么他可以毫无困难地更新他的修改。但是,当Martin想要提交他的修改时,并发控制策略就会开始起作用。源代码控制系统会检测到在Martin的修改和David的修改之间存在着冲突,因而拒绝Martin的提交,并由Martin负责指出怎样处理这种情况。如果使用悲观锁策略,只要有人先取出文件,其他人就不能对该文件进行编辑。因此,假如是Martin先取出了文件,那么David就只能在Martin完成任务并提交之后才能对该文件进行操作。

     

    多种技术处理死锁:一种是使用软件来检测死锁的发生。另一种是给每一个锁都加上时间限制,一旦到达时间限制,所加的所就会失效,工作就会丢失。

     

    软件事务经常使用ACID的属性来描述。

    原子性(Atomicity):在一个事务里,动作序列的每一个步骤都必须是要么全部成功,要么所有的工作都将回滚。部分完成不是一个事务概念。

    一致性(Consistency):在事务开始和完成的时候,系统的资源都必须处于一致的、没有被破坏的状态。

    隔离性(Isolation):一个事务,直到它被成功提交之后,它的结果才对其他所有的事务是可见的。

    持久性(Durability):一个已提交事务的任何结果都必须是永久性的,即“在任何崩溃的情况的能保存下来”。

    大多数企业应用是在数据库方面涉及到事务的,但还有很多情况要进行事务控制,比如说哦消息队列、打印机和ATM等。为了处理最大的吞吐率,现代的事务处理系统被设计成保证事务尽可能短,尽可能不让事务跨越多个请求;尽可能晚打开事务。

     

    五、分布策略

    按类模型进行分布的方法不可行的主要原因与计算机的基本特点有关。进程内的过程调用非常快。两个对立进程间的过程调用就慢了一个数量级。在不同机器间运行过程又要慢一两个数量级,取决于网络拓扑。

    本地接口最好是细粒度接口。但细粒度不能很好地用在远程调用中。分布对象设计第一定律:不要分布使用对象,大多数情况下是使用集群系统。

     

    六、一些关于具体技术的建议

    1、  JavaJ2EE

    企业级Java BeanEJB)的价值有多大,这个是JAVA世界中最大的争论。但是要构建良好的J2EE引用,其实并不需要EJB。使用POJO(普通Java对象)和JDBC同样能够完成这一任务。J2EE的设计选择随使用的模式不同而不同,同样,也受到领域逻辑的制约。

    2.NET

    .NETVisual Studio以及微软世界应用中,其中起决定作用的模式是表模块。.NET大力宣传Web Services,但是我不会在一个应用程序内部使用Web Services,而只会像Java中一样,使用它们作为一种允许应用集成的表现层。

    2、  存储过程

    3、  Web Services

        Web Services使得重用成为现实,并最终导致系统集成商的消失。

    4、  其他分层

     

     七、模式

     

    领域逻辑模式

    1、事务脚本:使用过程来组织业务逻辑,每个过程处理来自表现层的单个请求。

    事务脚本置于何处将取决于你如何组织你的软件层次,它可能会位于服务器页面、CGI脚本和分布式会话对象中。我喜欢尽可能的分离事务脚本。至少应当将它们放在不同的子程序中,而更好的方法则是将它们置于与其他处理表现层和数据源层的类相独立的类中。此外,绝不要让事务脚本调用任何表现层逻辑;这样会使我们容易修改代码和测试事务脚本。

    可以用两种方法来把事务脚本组织成类。一种是把多个事务脚本放在一个类中,每个类围绕一个主题将相关的事务脚本组织在一起。另一种方法则是每个事务脚本对应一个类,通过命令模式来完成消息传递。

    2、领域模型:合并了行为和数据的领域的对象模式。

    领域模型按照它的复杂程度分,可以分为:简单领域模型和复杂领域模型。简单的领域模型如【活动记录】,可以应对领域逻辑比较简单的系统。复杂的领域逻辑需要复杂的领域模型。

    3、表模块:处理某一数据库表或视图中所有行为的业务逻辑的一个实例。

    表模块以一个类对应数据库中的一个表来组织领域逻辑,而且使用单一的类实例来包含将对数据进行的各种操作程序。它与领域逻辑的主要区别在于,如果你有许多订单,领域模型对每一个订单都有一个对象,而表模块则只用一个对象来处理所有的订单。

    4、服务层:通过一个服务层来定义应用程序边界,在服务层中建立一组可用的操作集合,并在每个操作内部协调应用程序的响应。

     

     

    数据源架构模式

    1、表数据入口:充当数据库表访问入口的对象。一个实例处理表中所有的行。

    表数据入口包含了用于单个表或视图的所有SQL,如选择、插入、更新、删除等。其他代码调用它的方法来实现所有与数据库的交互。

    2、行数据入口:充当数据源中单条记录入口的对象,每行一个实例。

    3、活动记录:一个对象,它包装数据库表或视图中某一行,封装数据库访问,并在这些数据上增加了领域逻辑。

    4、数据映射器:在保持对象和数据库彼此独立的情况下在二者之间移动数据的一个映射器层。

    数据映射器是分离内存对象与数据库的一个软件层。其职责是在内存对象与数据库之间的传递数据并保持它们彼此独立。有了数据映射器,内存对象甚至不需知道数据库的存在;它们也不需要SQL接口代码,当然也不需要知道数据库方案。由于数据映射器是映射器的一种形式,因此数据映射器自身根本不为领域层所察觉。

     

    对象—关系行为模式

    1、工作单元:维护受业务影响的对象列表,并协调变化的写入和并发问题的解决。

    工作单元是一个记录这些变化的对象。只要开始做一些可能会对数据库有影响的操作,就创建一个工作单元去记录这些变化。每当创建、改变或者删除一个对象时,就通知此工作单元。

    工作单元的关键是在提交的时候,它决定要做什么。它打开一个事务,做所有的并发检查(使用悲观离线锁和乐观离线锁)并向数据库写入所做的修改。开发人员根本不用显式调用数据库更新方法。这样,他们就不必记录所修改的内容或者不必担心的引用完整性如何影响他们的操作顺序。

    2、标识映射:通过在映射中保存每个已经加载的对象,确保每个对象只加载一次。当要访问对象的时候,通过映射来查找他们。

    3、延迟加载:一个对象,它虽然不包含所需要的所有数据,但是知道怎么获取这些数据。

    实现延迟加载的四种方法:延迟初始化、虚代理、值保持器、重影。

     

    对象—关系结构模式

    1、标识域:为了在内存对象和数据库行之间维护标识而在对象内存的一个数据库标识域。

    数据库中通过主键来区分数据行,然而,内存对象不需要这样一个键,因此为对象系统能够保证正确的身份确认(在C++中是直接用原始内存位置)。

    2、外键映射:把对象间的关联映射到表间的外键引用。

    3、关联表映射:把关联保存为一个表,带有指向(有关联所连接的)表的外键。

    4、依赖映射:让一个类的部分类执行数据库映射。

    5、嵌入值:把一个对象映射成另一个对象表的若干字段。

    6、序列化LOB:通过将多个对象序列化到一个大对象(LOB)中保存一个对象图,并存储在一个数据库字段中。

    7、单表继承:将类的继承层次表示为一个单表,表中的各列代表不同类中的所有域。

    8、类表继承:用每个类对应一个表来表示类的继承层次。

    9、具体表继承:用每个具体类对应一个表来表示类的继承层次。

     

    对象—关系元数据映射模式

    1、元数据映射:在元数据中保持关系—对象映射的详细信息。

    元数据映射使开发者可以以一种简单的表格形式来定义映射,这些映射可由通用代码来处理,从而实现读取、插入和更新数据的细节。使用元数据映射最主要的决策是如何根据运行代码来表示元数据中的信息。有两种主要的途径:代码生成和反射编程。

    2、查询对象:描述一次数据库查询的对象。

    3、资源库:协调领域和数据映射层,利用类似于集合的接口来访问领域对象。

     

    WEB表现模式

    1、模型—视图—控制器(MVC):把用户界面交互分到不同的三种角色中。

    2、页面控制器:在WEB站点上为特定页面或者动作处理请求的对象。

     

    3、前端控制器:为一个WEB站点处理所有请求的控制器。

    4、模板视图:通过在HTML也面中嵌入标记向HTML发送消息。

    5、转换视图:一个视图,它一项一项地处理领域数据,并且把它们转换成HTML

     

    6、两步视图:用两个步骤来把领域数据转换成HTML。第一步,形成某种逻辑页面;第二步,把这些逻辑页面转换成HTML页面。

    7、应用控制器:一个用来处理屏幕导航和应用程序流的集中控制点。

     

    分布模式

    1、远程外观:为细粒度对象提供粗粒度的外观来改进网络上的效率。

    2、数据传输对象:一个为了减少方法调用次数而在进程间传输数据的对象。

    数据序列化

     

    离线并发模式

    1、乐观离线锁:通过冲突检测和事务回滚来防止并发业务事务中的冲突。

    2、悲观离线锁:每次只允许一个业务事务访问数据以防止并发业务事务中的冲突。

    3、粗粒度锁:用一个锁锁住一组相关的对象。

    4、隐含锁:允许框架或层超类型代码来获取离线锁。

     

    会话状态模式

    包括客户会话状态、服务器会话状态、数据库会话状态。

    通常使用数据传输对象来传输数据。数据传输对象可以在网络上序列化,因此,即使是很复杂的数据也可以传输。

    客户会话状态:将会话状态保持在客户端。客户会话状态有一定的优点。特别是支持无状态服务器对象,从而提高最大的集群性能和容错恢复。当然,如果客户崩溃了,它所有的会话数据就丢失了,但用户通常认为这合乎情理。对于安全问题,就要对传输的数据进行加密。

    客户数据传输:客户也需要存储数据。大客户的应用可以用自己的数据结构来存储。如果使用HTML,情况就复杂一些。一般有三种方法:URL参数、表单的隐藏域和Cookie

     

    服务器会话状态:将会话状态以序列化形式存放在服务器端。

    服务器会话里面最简单的一种方法是把会话数据放在应用服务器的内存中。可以将会话数据以会话标识号作为键标识存放在内存映射表中。只需要客户给出会话标识号,服务器就可以从映射表中取出会话数据。这种方法假设应用服务器有足够的内存处理,而且是只能有一个应用服务器,没有集群——如果这个应用服务器崩溃了,所有的会话数据就丢失得无影无踪。

    解决方案是将服务器会话状态序列化存放到数据库中,用一个以会话标识号为键值的表,表中需要有一个序列化LOB存放序列化后的会话状态。还要对作废的会话进行处理,尤其在一个面向顾客的应用中。一种方法是用一个监督进程检查并删除过期的会话,但这样会造成很多与会话表的连接。Kai Yu提供了他使用的一个好方法:将会话表分成12段,每两个小时轮换一次,轮换时先删除时间最旧的段中所有的数据,并把所有新的数据放到该段中。虽然这样会把那些超过24个小时的会话强制删除,但实际上不用去担心这样极少数的情况。

    实现举例:

    Java实现       最常用的服务器会话状态技术是使用HTTP会话或者使用有状态会话bean

    HTTP会话是让WEB服务器保存会话状态的一种简单方法。

    使用有状态会话bean,它需要一个EJB服务器。EJB容器负责持久和钝化处理,因此很容易实现。

    NET实现   服务器会话状态可以很容易地使用内建的会话状态功能实现。默认情况下,.NET将会话状态放在服务器进程内。也可以换成通过状态服务存取,可以在本地也可以在远程。如果使用远程的状态服务,可以在重启WEB服务器后依然使用原来的会话数据。通过在配置文件中指定是使用进程内方式还是使用状态服务,因此不必要修改应用程序。

     

    数据库会话状态是将会话数据作为已提交的数据保存到数据库中。

     

    基本模式

    1、  入口:一个封装外部或资源访问的对象。

    实际上这是一个十分简单的包装器模式。封装外部资源,创建一个简单的API,并用入口将对该API的调用转移到外部资源上。

    2、  映射器:在两个独立的对象之间建立通信的对象。

    映射器通常需要在层与层之间进行数据交换。这种数据交换一旦被激活,工作方式就是显而易见的。映射器的使用难点在于如何激活,因此你无法在被映射子系统中的任何一方直接调用它。有时可以使用一个第三方的子系统来完成映射并调用映射器。另一个可选的方案是让映射器成为某个子系统的观察者。通过监视子系统中发生的事件,映射器就可以调用了。

    3、层超类型:某一类型充当一层中所有类型的超类型。

    某一层中所有的对象都具有某些方法,但你并不希望这些方法在系统内被多次复制而产生冗余代码。此时你可以将这些行为移到一个通用的层超类型中。

    4、分离接口

    在一个包中定义接口,而在另一个与这个包分离的包中实现这个接口。

     

    5、  注册表

    一个众所周知的对象,其他对象可以通过该对象找到公共的对象和服务。

    6、  值对象:一个如货币或日期范围这样的小而简单的对象,判断时并不根据标识ID

    在由多种类型对象组成的对象中,区分引用对象和值对象是有用的。二者之中值对象通常规模小一些;它类似于许多非纯粹面向对象程序设计语言中的原始类型。通常来说,我们倾向于认为值对象是小对象,如货币对象或日期对象;而引用对象是大的对象,如订单或顾客。

    7、  货币:表示一个货币值

    面向对象的程序设计使你可以通过创建一个处理货币的货币类来解决货币与金额(小数点)这类问题。令人感到奇怪的是,居然没有任何主流的类库提供这个类。

    创建一个货币类,在其中保存金额和币种,可以以整数或定点小数的方式来保存金额。

    8、  特殊情况:针对特殊情况提供特殊行为的子类。

    9、  插件:在配置时而非编译时的连接类。

    10、服务桩:在测试时移除对有问题服务的依赖。

    企业级系统通常要依赖于第三方服务(例如信用评分、税率查询和价格引擎)的访问。有这类系统开发经验的开发人员都知道:如果依赖于完全不受自己控制的外部资源,通常会使软件项目受挫。第三方服务的特性是不可预知的,而且这些服务通常是远程的,因而软件性能和可靠性也会受到损害。

    这种依赖关系可能会导致测试无法进行,从而使得开发周期成倍增长。在测试时,用运行在本地的、快速的、位于内存中的服务桩来代替服务将会改善你的开发经验。

    当你发现对某一特定服务的依赖妨碍你的开发和测试时,就应当使用服务桩。许多XP的实践者使用术语“模拟对象”来代替服务桩。
    11
    、记录集:表格数据在内存中的表现方式。
       

    记录集模式的思想是通过一个内存中数据结构来提供解决这一问题的完整方案,该数据结构看起来与SQL查询的结果极为类似,但是它可以由系统中其他部件来生成和操控。

    记录集通常无需你亲自创建,而是由所有软件平台的销售商提供。ADO.NET中的data setJDBC2.0中的row set都是记录集的例子。

    目前有一种内存数据库sqlite,读取访问速度很快,有兴趣的可以研究,是开源的。

     

    展开全文
  • 软件开发大师谈企业应用架构模式

    千次阅读 2009-05-05 16:46:00
    企业应用架构模式(英文版)》——作者:Martin Fowler 多年来,Martin Fowler ——这位享誉世界的软件开发大师——见证了许多企业级应用项目。这些项目通常都包含相似的设计思路,事实证明这些设计思路可以有效...
    《企业应用架构模式(英文版)》

    ——作者:Martin Fowler

     多年来,Martin Fowler ——这位享誉世界的软件开发大师——见证了许多企业级应用项目。这些项目通常都包含相似的设计思路,事实证明这些设计思路可以有效地处理企业应用中不可避免的复杂性。本书就是将这些设计思路以模式形式表述的一个起点。

     

    查看详情

    本 书分为两个部分,第一部分是一些叙述性的章节,讨论企业级应用程序设计中的一些重要主题。这些章节介绍了企业级应用程序架构的各种问题及其解决方案,但解 决方案的细节没有深入讨论。解决方案的细节是在本书的第二部分中以模式的方式组织起来的。这些模式都是参考,读者可以从头到尾将第一部分的叙述性章节读 完,然后再根据兴趣和需求浏览第二部分的模式章节。因此,本书实际上是一本简短的叙述图书和详尽的参考书的二合一。

    本书讨论的是企业级应用程序的设计。企业级应用程序涉及大量复杂数据的显示、操作和存储以及对这些数据进行处理的业务流程的自动化。典型的例子有预订系统、财务系统、供应链系统以及许多其他支持现代商业运作的系统。

    虽然本书尚不全面,但仍可以为读者提供有关企业级应用程序架构方面的有益建议。本书讨论的主题包括:

    • 企业级应用程序的分层;
    • 构建领域(业务)逻辑;
    • 构建Web用户界面;
    • 将内存中的模块(特别是对象)与关系数据库关联起来;
    • 处理在无状态环境下的会话状态;
    • 分布的原则。

    这本书并不针对特定的软件平台,其中提到的所有模式几乎能够适用于所有已经和即将用于企业级应用的开发平台。

    本书为大多数模式提供了代码示例,但为提高可理解性,其中许多代码示例都有意简化了,你会发现需要做很多工作来处理所面临的更多需求。

    本书面向的是正在构建企业级应用,希望增进对架构相关问题的理解,加强此方面沟通的程序员、设计师和软件架构师。

    本书相关信息:http://blog.csdn.net/turingbooks/archive/2009/05/05/4152136.aspx

    展开全文
  • 企业应用架构模式 之 领域逻辑模式

    千次阅读 2007-06-28 01:22:00
    领域逻辑的组织可以分为三种主要的模式:事务脚本,领域模型,表模块。 面向过程的开发模式:事务脚本 事务脚本是这样一个过程开发逻辑:从表示层获得输入,进行校验和计算处理,将数据存储回数据库中,以及调用...
  •  .NET企业应用架构设计系列之开场白 .NET企业应用架构设计系列之技术选型 这里要说到的是关于三层架构中的应用服务器。对于电子商务网站来说,成熟的架构基本上都是采用分层式的。分层的结构一方面适合人脑的...
  • 关系,本篇可能主要是简单的介绍下企业应用的几类模式,结合这几个分层直接的交互来完成系统功能的构建。我们还是先对我们学习的四个分层的职责和功能做个大 概的回顾,我们先来看看下图来回顾下我们讲述的内容。
  • Java企业应用架构设计中的分布式结构  2010-12-24 13:54:12| 分类:默认分类 | 标签:|字号大中小 订阅 Java企业应用架构设计是每个Java开发者不必学的知识,本文将对Java EE应用的架构与...
  • 企业应用架构模式之领域逻辑模式

    千次阅读 2012-10-12 11:33:55
    一般的,企业架构过程从领域层开始的,一些经典的领域逻辑方法也就被称之为领域逻辑模式。主要有:事务脚本、领域模型、表模块。选择依据实际领域逻辑的复杂性,事务脚本是最简单的,而领域模型则比较复杂。 (1...
  • .NET企业应用架构设计系列

    千次阅读 2011-01-24 23:47:00
    一、.NET企业应用架构设计系列之技术选型这里说的技术选型实际上是指技术方向的选择,或者叫平台方案的选择,也或者叫技术路线等,总之是大方向的把握。假定项目背景是要做一个中型WEB系统,公司组建新的技术团队...
  • 本系列课程以大量企业应用系统实例图为基础,把业界常用的架构设计逻辑方法诠释出来,从 (1)软件功能架构(2)逻辑架构(3)技术架构(4)部署架构,四个维度切中架构设计的在项目中的实际应用。让大家把理论与...
  • 以秒杀为例浅谈企业应用软件架构设计过程

    千次阅读 多人点赞 2015-01-27 17:19:18
    1、引言 本文不是学术性文章,也不是某些标准化理论的阐述,而是根据所从事J2EE应用软件架构设计工作的经验,谈谈自己对软件架构设计过程的理解,希望能让一些徘徊于门口的同学能对企业应用软件架构设计的目标、...
  • Java企业应用架构实践

    千人学习 2018-05-09 22:04:22
    基于Servlet、JSP、JDBC 一步一步敲代码的方式,实现一个企业应用架构实例,学员可以深层次理解Java架构的内涵
  • 接触《企业应用架构模式

    千次阅读 2004-10-08 19:00:00
    那么期待的长假,在狠狠饱睡几天之后居然有点想上班了,唉,真是 J 啊~ 前天去南山新开业的书城,没有找到《企业应用架构模式》(Martin Fowler著),呵,今天早上在 china-pub 上下了订单,中午就收到书了。...
  • 架构师必须掌握的重要微服务架构设计模式

    千次阅读 热门讨论 2021-03-02 22:36:29
    参考该文章 ...微服务架构设计模式列表: 独享数据库(Database per Microservice) 事件源(Event Sourcing) 命令和查询职责分离(CQRS) Saga 面向前端的后端 (BFF) API 网关 Strangler 断路器.
  • 企业应用架构模式读书笔记(一) 前年走马观花式的把这本书读了一遍,加上当时并没有实际使用,所以时隔不到两年,对本书中部分内容的印象已经有些模糊了。最近要用到这方面的知识,花点时间再读一遍,顺便记点笔记...
  • .Net企业应用架构设计之UML

    千次阅读 2012-09-07 22:33:02
    这篇博客之所讲UML出现在了《Microsoft.Net企业应用架构设计》一书的第二章,从架构上讲不应该出现这节知识点,但是从架构师的职责角度,UML知识点是一个基础,因此作者独立出了一个章节。大家在学生时代都有学习...
  • 以美的名义 熊节 Patterns of Enterprise Application Architecture 《企业应用架构模式》 Martin Fowler 电力出版社2004年4月影印版 我有一双定做的休闲鞋,一只鞋上赫然写着“KISS”,另一只则写着“YAGNI”...
  • 架构部分 架构 Martin Fowler 给"架构"这个词做了两点归纳:1.最高层次的系统分解 2.系统中不易改变的决定 它包括了一些开发者希望能够及早做出的...在架构模式中,层次是最为重要的,Martin Fowler的>全书都在阐释怎么
  • 前段时间刚刚看完了《Microsoft .Net企业应用架构设计》一书,以后陆续的分享作者在书中的精华,简明扼要的进行总结和概述。同时这本书推荐给有兴趣的童鞋。软件架构到底是什么 每次遇到软件项目时,我们都会创建...
  • 读-Martin Fowler-企业应用架构模式

    千次阅读 2016-11-03 17:26:47
    数据源架构模式 表数据入口 行数据入口 活动记录 数据映射器 ormapping 基本模式 入口 映射器 层超类型 分离接口 注册表 值对象货币 特殊情况 插件 服务桩 记录集 现在 大师级人物Martin Fowler的书,04年出版,...
  • 这次主要分享一下在架构设计过程中涉及的基础知识,主要是涵盖系统架构方法、架构模式及设计模式,便于大家在后续一起探讨HRMS系统的SaaS模式的架构设计。 一、设计模式  大家或多或少的都接触并在实际的开发过程...
  • 中小企业WEB网站架构与程序设计模式-程序设计论文-设计论文 文章均为...研究分析了中小企业应用程序的设计模式 关键词:WEB网站设计模式运行架构 引言 Web应用程序是一种经由Internet或Intranet以Web方式提供服务的程
  • 系统架构师谈企业应用架构之系统建模1 系统架构师谈企业应用架构之系统建模2 系统架构师谈企业应用架构之系统建模3 系统架构师谈企业应用架构之系统建模4 在上篇中我们讲解了几类UML2.0语言新推出的建模...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,074
精华内容 69,629
关键字:

企业应用架构设计模式