目标
学习如何为应用程序设计一个合适的架构
了解对设计进行审查的各种方式
概要
本文将依次介绍应用设计的六个主要步骤并讨论与逻辑选择相关的各种问题。文中还包含了检查设计时可供参考的表单。
输入
在设计应用架构的时候以下输入是非常有用的:
- 用例与使用场景
- 功能需求
- 非功能性需要(如性能、安全性、可靠性等质量属性)
- 技术需求
- 部署环境
- 各种限制条件
输出
设计应生成以下结果:
- 突出架构特点的用例
- 架构的危险区域
- 可用的架构
- 架构测试点
步骤
图1即是应用架构设计的五个主要步骤。
图1 应用构架设计的主要步骤
这些步骤分别是:
步骤1 确定架构目标。清晰的目标能让你更好地考虑并解决架构相关问题。正确的目标能让你知道什么时候该结束,什么时候该迈向下一步。
步骤2 关键场景。使用关键场景来帮你确定最重要的因素,以及对可用架构做出评估。
步骤3 对应用的了解。了解你的应用类型、部署架构、架构特点及相关技术,以让你的设计更符合实际。
步骤4 主要危险区域。根据质量属性与架构框架确定主要的危险区域。这些区域是在设计应用的时候最容易出错的地方。
步骤5 可选方案。创建备用架构或架构测试点并按场景、危险区域、部署条件对其进行评估。
随着设计的发展,你会逐渐发现越来越多的影响架构的细节,架构也因此逐渐丰满起来。别想一步就完成整个架构的构建,也别被细节迷惑,要先为架构设计一个基本框架,把注意力放在主要步骤上。
步骤1 确定架构目标
架构目标即是组成设计过程、确定使用范围并帮你确定什么时候该结束的因素。在设定架构目标的时候请考虑以下基本点:
·从一开始就要对架构目标有个清楚的认识。架构与设计的各个阶段所花费的时间将取决于这些目标。比如,你是在搭建一个原型?测试潜在的方式?还是准备为新应用创建一个长远的架构环境?
·了解架构的消费者。要确定架构是否会被其他设计师、开发人员、测试人员、业务人员或管理人员使用。确定架构受众的需求,以让架构更为成功、更有影响力。
·了解条件限制。了解技术限制、使用限制、和部署限制。从一开始就要了解这些限制,这样你才不会在将来遇到一些意想不到的麻烦。
步骤2 关键场景
关键场景包括使应用获得成功的最重要的场景,还有能突出架构特点的用例。
重要的场景标准如下:
1.这些场景是业务关键的,比其它功能具有更高的使用要求,或者具有很高的技术/工艺风险。
2.关系到功能属性和质量属性两个方面,或者具有交叉性的影响。比如CRUD操作对安全性非常敏感。
3.它们是最重要的场景,贯穿应用的各层(级),或者对应用整体都有重要的影响。
架构突出的用例标准如下:
1.这些用例对应用部署的成功和验收非常重要。
2.能够对设计进行足够的检验。
区别系统场景与用户场景的不同是很重要的。
系统场景指主要对应用与设备的内部操作产生影响的场景。比如在各层间传递的信息、连接数据存储、执行验证等。
用户场景指用户发起或受用户控制的场景。比如创建一个定单、浏览产品、或者更新客户记录。
突出架构特点的用例举例:
用在线商场的程序创建一个订单并接收定单被确认的信息。
使用库存管理程序更新某个产品记录,并更新所有相关的记录(比如价格列表)。
在CRM程序中搜索并显示某个客户的细节。
步骤3 对应用的了解
了解你的应用在完成的时候的大概情况。这将会使你的架构更实际,并与具体的条件限制和决定有更密切的联系。创建应用的大概视图应该包括以下步骤:
- 决定应用的类型。首先决定所构建的应用的类型。它是一个移动应用、富客户端、服务、网络应用、还是组合应用?
- 了解部署限制。然后,了解所部署的目标环境和它将对架构产生什么影响。
- 确定重要的架构特点。确定你的架构将使用哪些类型。面向服务的架构?客户服务器?分层?消息总线或是某几种的组合?
- 确定相关的技术。最后,根据应用类型和各种条件限制确定相关的技术。
决定应用的类型
选择正确的应用类型是应用架构设计的关键。需求和设备限制决定了合适的应用类型。以下几点将帮助你做出合适的选择。
- 移动应用可以作为瘦客户端或富客户端。富客户端移动应用可以支持非联网或偶然联网的场景。网络应用或瘦应用只支持联网场景。设备资源将成为这种设计的条件限制。
- 富客户应用通常是独立的应用,可以使用多种控制手段在图形界面上显示数据。富客户应用可以用于支持非联网和偶然联网的场景,因为这种应用是运行在客户机上的。
- 富因特网应用可以支持多平台和多浏览器并显示多媒体和图形内容。富因特网应用运行在浏览器沙盒上,其对客户端的访问受到限制。
- 服务应用用于实现客户与服务器之间的松耦合。服务可以让用户从本地或远程访问复杂的功能。服务操作使用基于基于XML的消息格式的传送机制。
- 网络应用通常支持联网场景,通常支持多浏览器和多操作系统平台。
了解部署限制
在设计应用架构的时候,你必须同时考虑企业的政策和程序以及目标部署设备。在目标环境确定的情况下,你的应用设计必须能够反映出实际存在的各种限制。你在进行设计的时候必须考虑到服务质量(QoS)属性,比如安全性和易维护性。有时候由于政策程序上的限制或网络布局的原因,你必须作出一些折衷措施。
要在设计过程的早期确定这些需求和限制,这样你才能尽早地选择合适的部署环境、解决应用与设备架构之间的冲突。
1.分布式与非分布式架构
应用部署通常有两种方式:
非分布式部署 除了数据存储功能,其它功能和层都在同一服务器上。
分布式部署 各层与应用分布在不同的物理级上。
在大部分情况下,我们都建议采用分布式。虽然当一个过程需要跨越物理界限的时候需要对数据进行序列化,因此性能会受到影响。但是由于某些原因我们需要把功能分散到各服务器上。另外,你也可以根据服务器的位置选择最优化的通信协议。
非分布式部署
在非分布式的架构中,呈现、业务和数据存取代码虽然在逻辑上是分开的,在物理层面上却是位于同一网络服务器上的。图2描述了这样的场景。
图2 非分布式部署
优势
非分布式架构更为简单。
由于本地调用,非分布式架构具有性能上的优势。
劣势
难于与其它应用共享业务逻辑。
服务器资源是跨层共享的。这既有好的一面也有不好的一面--因为总有一层处理繁忙状态,如果各层合作良好,资源就能获得充分利用。但是一旦某一层要求更多的资源,其它层可能就会无法利用资源。
分布式部署
如图3所示,分布式部署可以让你把应用的不同层分布在各物理级上。
图3 分布式部署
优势
分布式架构易于扩展,并且可以独立地加载平衡业务逻辑。
各层有自己的资源可以利用。
灵活。
劣势
需要额外的序列化,并由于远程调用而产生网络延迟。
通常更为复杂、更为昂贵。
2.保持相同的过程
尽量避免远程调用。由于序列化和网络延迟等原因,跨物理界限(过程和机器)的远程调意味着昂贵的成本。如图4所示,你可以在当前的服务器中添加更多的硬件或者在网络应用级中添加更多的服务器。
图4 在网络应用级中添加服务器
你可以把应用的业务逻辑寄存到网络服务器上,或者一个物理意义上独立的应用服务器上。通过把业务逻辑放到网络服务器的网络应用过程中,你可以获得最佳的性能。只要你在应用设计中能够避免或可以利用服务器亲和力,你就可以使用这种方法进行扩展。
3.除非必须,否则不要把应用逻辑放在远程
除非你确实需要这么做,或者已经做过权衡对比,否则决不要把业务逻辑层分离出去。远程逻辑会增加性能成本。这是在网络中环行所造成的网络延迟和序列化必然导致的结果。
然而,你可能确实需要从物理级上将业务层分离出去,比如以下场景:
- 你可能想把网关服务器和关键的合作伙伴放到一起。
- 你可能需要为既有的一套业务逻辑添加一个网络前端。
- 你可能需要在多个客户端应用之间共享业务逻辑。
- 企业的安全政策不允许在前端网络服务器上安装业务逻辑。
- 可能你的业务逻辑对运算速度非常敏感,所以你需要把这个处理过程减负到一个单独的服务器上。
确定重要的架构特点
有许多会影响架构特点的因素。其中包括企业的设计与实现能力、开发人员的能力与经验、设备限制与部署场景等。
主要架构模式有几下几种:
- 客户服务器。分离系统,客户向服务器发送请求。
- 基于组件。将应用设计分解为可重用的组件,用户界面良好。
- 分层。以层为单位将系统分解为各功能相近的组。
- 消息总线。为所有连接到系统的组件定义一组通用格式,因此各组件无需了解接收方的实际信息。
- 面向对象。一种将任务以对象为基础进行分解的程序设计方法。
- 面向服务(SOA)。应用根据合约与信息以服务的方式呈现或使用功能。
一个完整的结构通常包含几种模式。比如,一个分层的架构可以与基于组件、面向对象或面向服务的架构模式一起使用。可以这样选择架构模式。
以下是选择客户服务器架构模式的情况:
- 你的应用是基于服务器的,可以支持多个客户端。
- 你创建的是通过网络浏览器呈现的网络应用。
- 你的业务过程需要能被公司所有人使用。
- 所创建的服务要供其它应用使用。
- 你想让数据存储、备份和管理功能集中化。
- 你的应用必须支持各种客户端类型和设备。
以下是选择基于组件的架构模式的情况:
- 你已经有了合适的组件,或者可以从第三方获得合适的组件。
- 你的应用永远都是用于执行程式化的功能的,可能不需任何输入。
- 你的应用相对简单,无需一个完整的分层架构。
- 你的应用是为了满足特定的需求而产生的,没有用户界面或业务过程。
- 你想把使用不同代码语言编写的组件结合到一起。
- 你想创建一个便于替换和更新私人组件的插件式架构。
以下是选择分层架构模式的情况:
- 应用比较复杂,所以你想分组各种功能问题以简化问题。
- 你想通过减少依赖关系来提高可维护性与扩展性。
- 你已有通过服务接口呈现合适的业务过程的应用。
- 你的应用必须支持各种客户端类型和设备。
- 你想实现复杂的和/或可配置的业务规则和过程。
以下是选择系统总线架构模式的情况:
- 当前的应用之间有互操作。
- 你在执行一个需要与外部应用进行交互的任务。
- 你在执行一个需要与寄存在另一个环境中的应用进行交互的任务。
- 当前的应用执行一些特殊的任务,你希望把这些任务整合成一个操作。
以下是选择面向对象的架构模式的情况:
- 你要根据实际对象和行为对应用进行模拟。
- 你已有符合需求的合适的对象和类。
- 你需要将逻辑与数据一起封装到可重用的组件中。
以下是选择面向服务的架构模式的情况:
- 你能够访问到适合的服务,或者可以购买到托管公司的所需服务。
- 你希望为包含各种服务的应用程序构建一个统一的用户界面。
- 你在创建SS、SaaS或基于云的应用。
- 你需要支持应用中各段之间的基于消息的交流。
- 你需要以平台无关的方式呈现功能。
- 你希望利用联邦服务,比如认证。
- 你希望以目录的方式呈现服务,并且首次接触这个界面的用户也可以使用。
确定相关的技术
在选择技术时,需要考虑的关键因素是你的应用类型和你希望使用的应用部署结构及架构模式。技术的选择也受到企业政策、设备限制、资源能力等的控制。比如你想构建一个SOA模式的应用,那么WCF就是不错的选择。如果你要构建可以调用WCF服务的网络应用,那么ASPNET是不错的选择。你的技术选择和你的应用模式具有直接的关系。
不妨考虑一下以下问题:
- 哪种技术能为你提供架构模式上的支持?
- 哪种技术能为你提供应用模式上的支持?
- 哪种技术能为你的应用提供质量属性上的支持?
步骤4 主要危险区域
确定架构中最容易出错的区域。可以通过质量属性和交叉问题对危险区域进行整理。
质量属性
找出对于应用和场景很重要的质量属性。比如,大部分应用程序都需要解决安全性与性能的问题,而这些问题还需要根据易用性、灵活性等可能更为重要的属性进行权衡分析。
以下是需要注意的重要的质量属性。
范畴 |
注意事项 |
有效性 |
如何设计故障转移支持 |
|
如何设计一个备用站点 |
|
怎样计划备份与恢复 |
|
如何设计运行时的更新 |
概念完整性 |
如何分离对外部的依赖性 |
|
如何整合旧技术 |
|
如何在不打断客户的情况下发展系统 |
灵活性 |
如何处理动态业务规则 |
|
如何处理动态UI |
|
如何处理数据与逻辑过程中的变化 |
|
如何处理业务需要的变化 |
互操作性 |
如何让应用在独立发展的同时实现互操作 |
|
如何通过服务接口分离系统 |
|
如何通过层的映射分离系统 |
易维护性 |
如何减少层与组件之间的依赖性 |
|
如何实现一个插件式的架构 |
|
如何选择合适的通信模型 |
易管理性 |
如何了解主要的失败模式 |
|
如何对系统操作与健康状态进行监控 |
|
如何根据负载对系统进行调整 |
性能 |
如何确定缓存策略 |
|
如何设计层间的高性能通信 |
|
如何设计高性能数据存取 |
|
如何有效地管理资源 |
可靠性 |
如何处理不可靠的外部系统 |
|
如何审查请求与任务 |
|
如何对负载进行重定向 |
|
如何处理失效的通信 |
|
如何处理失效的操作 |
|
如何处理异常 |
重用性 |
如何减少层与组件之间的重复性 |
|
如何实现跨系统的共享 |
|
如何实现组件和层之间的功能共享 |
可扩展性 |
如何设计可扩展的层与级 |
|
如何扩展 |
|
如何处理传输与负载的测试点 |
安全性 |
如何解决认证与授权问题 |
|
如何防止恶意输入 |
|
如何保护敏感数据 |
支持 |
如何设计审查与记录 |
|
如何设计使用问题信息的记录 |
易测性 |
如何设计才能方便测试 |
|
如何设计单元测试 |
|
如何设计UI自动化 |
可用性 |
如何设计才能让用户有更多的权限 |
|
如何改善响应性 |
|
如何避免常见的用户体验问题 |
架构框架
架构框架代表了你在层与级上可能会遇到的交叉问题。这些也是最容易出现重大设计错误的区域。可以通过架构框架来发现需要额外注意危险区域。
你可以使用以下架构框架来发现需要额外注意的交叉问题。
领域 |
描述 |
认证与授权 |
如何选择认证策略 |
|
如何选择授权策略 |
|
如何在不同层与级之间传递身份消息 |
|
如何在不使用活动目录的情况下存储用户的身份信息 |
缓存与状态 |
如何选择合适的缓存技术 |
|
如何决定缓存哪些数据 |
|
如何决定在哪里缓存数据 |
|
如何检查过期策略 |
通信 |
如何为不同的层与级选择合适的通信协议 |
|
如何设计层之间的松耦合 |
|
如何实现异步通信 |
|
如何传送敏感数据 |
组合 |
如何为用户界面选择组合模式 |
|
如何避免UI模块之间的依赖性 |
|
如何处理UI模块之间通信问题 |
并发与事件 |
如何处理并发线程 |
|
如何选择积极并行与保守并行 |
|
如何处理分布式事件 |
|
如何处理长期事件 |
配置管理 |
如何确定需要配置的信息 |
|
如何确定在哪里储存配置信息 |
|
如何保护敏感配置信息 |
|
如何处理簇中的配置信息 |
耦合与内聚 |
如何选择合适的层策略来分离问题 |
|
如何在层里设计高内聚的组件并对其分组 |
|
如何确定松耦合是否适合层里的组件 |
数据存取 |
如何管理数据库的连接 |
|
如何处理异常 |
|
如何改善性能 |
|
如何处理二进制大对象(blob) |
异常管理 |
如何处理异常 |
|
如何记录异常信息 |
|
如何在需要的时候进行通知 |
日志与器械 |
如何决定记录哪些信息 |
|
如何让日志可修改 |
|
如何确定需要什么等级的器械 |
用户体验 |
如何提高任务的有效性与效率 |
|
如何改善响应性 |
|
如何提高用户权限 |
|
如何改善外观与体验 |
验证 |
如何确定在什么位置怎样执行验证 |
|
如何验证长度、范围、格式、类型 |
|
如何限制及拒绝输入 |
|
如何整理输出 |
工作流 |
如何选择合适的工作流技术 |
|
如何处理同一工作流中的并发问题 |
|
如何处理工作流中的错误 |
|
如何编排工作流中的过程 |
步骤5 可用方案
定义了危险区域之后,你就可以创建第一个高层次的设计并着手创建一个可用架构。你可以返回第二步对可用方案及你所定义的关键场景和需求进行再次验证。
架构测试点一种是用来确定具体的设计方式的可行性的设计原型。你可以使用架构测试点来减少风险并迅速检验各种方式的健全性。根据关键场景和危险区域对架构测试点进行测试。
迭代与递增式的架构
这个架构过程应该是迭代和、递增式的。你的第一个可用方案是一个高层次的设计,可以根据针对关键场景、需求、各种限制等进行测试。在你创建了可选架构和架构测试点之后,你将会了解到更多的细节,从而丰富你的场景、应用视图和解决危险区域的方法。每个迭代周期都应该为你的设计添加更多的细节。
下一步怎么做
在你结束了架构建模之后,你可以这样:
如果你把可用架构和架构的测试用例保存在了一个文件里,那么请不要随便往这个文件添加任何多余的东西、避免过分的格式化,这样你可以随时对其进行更新。其主要内容应该包括你的目标、应用类型、部署方式、关键场景、需求、技术、质量属性和测试。
使用质量属性来帮助你的设计与实现。比如,开发人员应该注意与已确定的架构风险相关的反模式,并使用模式协助解决这个问题。
使用架构框架来计划并整理架构测试。
与相关团队成员交流你得到的信息。包括你的应用开发团队、测试团队、以及网络与系统管理员。
如何实现架构的敏捷
使用系统需求和用户需求对可以再次测试的用例的实例进行检验。一个优秀的需求应该能够贯穿架构中用户、业务和系统三个方面。使用用例来对设计进行测试,确定系统中虚弱的部分。系统需求从系统的角度描述应用场景。用户需求从客户的角度描述应用应该可以完成什么任务。这样,你就会根据用途描述需求,并根据质量属性进行检验。你应该在一个迭代周期内完成一个需求所描述的功能。随着架构模型的更新,你可能还需要创建新的需求描述。
在你制定需求描述的时候请注意以下几点:
- 在项目的早期创建能够对架构的所有层进行检验的可选架构,从而减少风险。
- 关于利用架构模型,根据场景、功能需求、技术需求、质量属性和限制条件调整架构、设计和代码。
- 根据你当前的知所创建架构模型,并写出在接下来的需求和迭代周期中必须解决的问题。
- 对架构做出足够多的调整后,可以考虑写一个能够反映这些调整的需求描述。把这些调整放到一起解决。
在创建架构的测试点的时候,请考虑以下几点:
- 了解你所面临的最大风险,根据这些风险对设计进行调整。
- 在敏捷方法中,信息共享是非常重要的;让你的交付成果能够实现更好的信息交流。
- 创建架构的时候要考虑到灵活性与重构的问题。你可能需要对架构进行多次调整。
审查架构
对应用架构进行审查是一项非常重要的任务,因为它能够减少错误、尽早地发现并修复架构问题。架构审查是公认的可以降低项目成本、减少架构故障的有效措施。因此在创建架构的时候要让其尽可能地方便交流和审查。这不仅可以提高架构质量,也能减少每次审查所需的时间。
架构审查的主要目标是确定架构能够正确地实现所需的功能并符合质量属性。此外,它还能帮助发现并解决问题。
场景评估
场景评估是进行架构审查的有效方法。在场景评估中,主角是对业务最重要的场景,也是对架构影响最大的场景。以下是几种常用的审查方法:
软件架构分析方法(SAAM)
最初,SAAM是用来评估可修改的特性的。但是后来这一方法被延用到架构审查中,主要面向可修改性、可移植性、可扩展性、整合性以及功能覆盖率等质量属性。SAAM也被用来审查架构的性能、可靠性。
软件架构权衡分析法(ATAM)
ATAM法是SAAM的精炼、改进版本,用于审查架构决策的质量属性、以及具体质量目标的完成度。
主动设计审查(ADR)
这种架构审查方法最适用于未完成或正在进行中的架构。其主要不同点在于每次的审查目标是架构的某个区域而不是架构的整体。
设计中主动审查(ARID)
这种架构审查技术组合了ARD对进行中架构的一系列问题的审查,和ATAM与SAAM的对质量属性的场景审查。
成本效益分析法(CBAM)
这种架构审查方法主要是分析架构决策的成本、收益和对进度的影响。
软件可变性分析(ALMA)
对商业信息系统(BIS)架构的可变性进行评估。
架构系评估方法(FAAM)
这种架构审查技术评估的是信息系统类架构的互通性和扩展性。
沟通
架构设计完成之后,你必须和其他利益相关人讨论这个设计。利益相关人包括开发团队、系统管理员和操作人员、业主以及其它相关团体。有许多关于如何向别人描述架构的方法,下面就是其中一种:
4-1法 这种方法使用了架构的五种视图。其中四种是以不同的方式对架构进行描述。逻辑视图(比如对象模型)、过程视图(比如从并行和同步的角度)、物理视图(软件各层与功能的分布式硬件配置图)和开发视图。第五种视图展示的是软件的场景与用例。这可以让利益相关人了解到他们更为关心的某些方面。
原文链接:How
To - Design Using Agile Architecture |