架构的驱动力(影响最终软件架构的重要事情
)
包括下面这些:
功能需求:需求驱动架构。不管怎么捕捉和记录需求(比如,用户故事、用例、需求规格书、验收测试等),你都要大概知道你在构建什么。
质量属性:非功能需求(比如,性能、可扩展性、安全等)通常是技术方面的,也很难改造。理论上,这些都需要体现在初始的设计中,忽视这些属性会导致软件系统要么做得不够,要么做得太过。
约束:约束普遍存在于现实世界,包括批准的技术清单、规定的集成标准、目标部署环境、团队规模等。再说一次,不考虑这些会导致你交付的软件系统与环境不匹配,增加不必要的摩擦。
原则:是在试图为软件提供一致性和清晰度时你想要采用的东西。从设计的角度来看,这包括你的分解策略(比如,层、组件和微服务的对比)、关注点分离、架构模式等。明确概述一套初始的原则至关重要,这样构建软件的团队才会朝着同一方向出发。
C4理论
软件系统由多个容器构成,容器又由多个组件构成,组件由一个或多个类实现。大多数软件系统都可以用这种简单的逻辑结构单元的层级关系来建模。
类:对我们大多数人来说,在一个面向对象的世界里,类是软件系统的最小结构单元。
组件:组件可以想象成一个或多个类组成的逻辑群组。比如,其他组件可以使用审计组件或认证服务,来确定对特定资源的请求是否放行。组件通常由多个类在更高层次的约束下组合而成。
容器:容器是指一个在其内部可以执行组件或驻留数据的东西。它可以是从网络或应用服务器直到富客户端应用或数据库的任何东西。作为整个系统的一部分,容器通常是可执行文件,但未必是各自独立的流程。比如,我把每个Java EE网络应用或.NET网站都看作一个独立的容器,不管它们是否运行在同一个物理服务器流程中。从容器的角度理解一个软件系统的关键在于,任何容器间的通信可能都需要一个远程接口,比如SOAP网络服务、RESTful接口、Java RMI、Microsoft WCF、报文,等等。
系统:系统是最高的抽象层次,代表了能够提供价值的东西。一个系统由多个独立的容器构成,例如金融风险管理系统、网络网银行系统、网站等。
非功能性需求
非功能性需求通常被看作是“能力”,主要跟服务质量有关。按理说,比非功能性需求更好的说法是“系统特征”或“质量属性”,但不太常用。下面大致列出了常见的质量属性。
1. 性能
性能就是一个东西有多快,通常指响应时间或延迟。
响应时间:从发出请求到收到响应所用的时间,比如用户点击网页中的超链接或桌面应用程序中的按钮。
延迟:消息从A点到B点,通过你的系统所用的时间。就算构建的不是“高性能”软件系统,性能也可应用于Web应用程序、桌面应用程序、面向服务架构、消息系统等几乎所有你要构建的软件系统。如果用户说你的软件“太慢”,你就明白为什么有一些性能的概念很重要。
2. 可伸缩性
可伸缩性基本上就是软件处理更多用户、请求、数据、消息等的能力。可伸缩性和并发机制密不可分,因此能在相同的时间内处理更多的东西(比如每秒的请求)。
3. 可用性
可用性是软件对服务请求的可操作和可见程度。你常会看到用“9”来衡量或指代可用性,如99.99%(“四个9”)或99.999%(“五个9”)。这些数字指的是正常运行时间的百分比。硬币的另一面是可以容忍的停机时间。99.9%(“三个9”)的正常运行时间意味着留给计划维护、升级和意外故障的时间每天只有1分多钟。
4. 安全性
安全性涵盖了从认证和授权到数据在运输和储存中的机密性的所有事情。和性能一样,安全性很有可能在一定程度上对你很重要。对于部署到互联网的Web应用程序,安全性应该被视为最基础的东西。开放Web应用程序安全项目(OWASP,Open Web Application Security Project)是学习安全性的一个很好的出发点。
5. 灾难恢复
如果失去一个运行了你的软件的硬盘、服务器或数据中心,会发生什么?灾难恢复处理的就是这些。如果你的软件系统至关重要,就会经常听到人们谈论业务连续性过程,也就是发生灾难事件时,应该做什么才能保持持续运行的状态。
6. 可访问性
可访问性通常是指像W3C的可访问性标准这样的东西,指的是如何让视觉障碍之类的残疾人也能使用你的软件。
7. 监测
有些组织对于应该如何监测软件系统才能确保它们正常运行和满足服务请求,有特定的需求。这可能包括将软件与平台特定的监测功能(比如Java平台的JMX)集成,或发生故障时向集中监测仪表发送警报(比如通过SNMP)。
8. 管理
监测通常提供一个软件系统的只读视图,有时会有运行时管理需求。例如,有必要的话,暴露一些功能,使得操作人员能够修改系统运行时的拓扑结构或配置元素,刷新只读缓存等。
9. 审计
人们往往需要一个引起软件系统中数据或行为变化的事件的日志(即审计日志),特别是涉及钱的时候。通常这些日志需要捕获与变动由谁做出、什么时候做出以及为什么做出相关的信息。变动本身(即变动前后的值)往往也需要记录。
10. 灵活性
灵活性是一个有点滥用和含混的术语,指的是软件执行多个任务,或以不同方式执行单个任务的“灵活性”。一个很好的灵活性需求的例子是非技术人员修改软件内部使用的业务规则的能力。
11. 可扩展性
可扩展性也是滥用和模糊的,但它指的是扩展软件使其可以做一些现在还不能做的事的能力,也许是通过使用插件和API。一些市面上的产品(如微软Dynamics CRM)允许非技术用户扩展存储的数据和改变其他用户与数据交互的方式。
12. 可维护性
可维护性往往被认为是一个需求,但这到底是什么意思?作为软件开发者,我们通常会努力打造“可维护”的软件,但值得我们思考的是,代码库以后将由谁来维护。可维护性很难量化,所以我宁愿思考我们可以遵循的架构和开发原则,因为这些是编写可维护的代码的驱动力。
13. 法律法规
有些行业受到当地法律或监管机构的严格管理,导致了与数据保留或审计日志等相关的额外需求。举个例子,大多数金融机构(投资银行、零售银行、信托公司等)为了保持在市场中的运作能力,必须遵守一些规则(如反洗钱)。
14. 国际化(i18n)
很多软件系统,特别是部署在互联网上的,不再以单一的语言交付。国际化是指以多种语言交付软件中用户可见元素的能力。这看似简单,当你试图将其加入已有软件时,才会意识到有些语言是从右向左书写的。
15. 本地化(l10n)
和国际化相关的是本地化,是指以符合最终用户文化习俗的方式展现数字、货币、日期等内容。有时候,国际化和本地化也统称为“全球化”。