什么是软件架构

软件应用程序架构是定义一个结构化解决方案,使其满足所有技术和操作需求,同时优化性能、安全性以及可管理性等质量要求的过程。

为什么架构很重要

风险通常是因为架构的问题而导致的,如不稳定、不支持已经存在的或未来的业务需求、或在生产环境中难于部署或管理。

系统的设计应该考虑用户、系统(底层IT架构)以及业务目标。针对其中的每个方面,你应该概括出主要场景,而且要识别重要的质量要求(例如,可靠性或性能要求)。

image

交集是有可能的,而且必须在三个方面的需求之间寻找平衡。架构关注应用程序中的主要元素和组件如何发挥作用,或者如何互操作。数据结构和算法的选择或独立组件的具体实现都是设计时要考虑的。

当考虑软件架构时,需要关注如下几个方面:

  • 用户如何使用应用程序?
  • 应用程序如何部署在生产环境,在生产环境中如何被管理?
  • 应用程序的质量需求都有哪些,如安全、性能、协作、国际化和配置?
  • 应用程序如何长期保持可扩展性和可维护性?
  • 现在或部署后可能影响你的应用程序架构的趋势?

架构的目标

应用程序架构是通过理解用例,然后试图构建一个业务需求和技术需求之间的桥梁。然后再寻找一种实现用例的方法。架构设计的目的是识别影响应用程序结构的需求。好的架构设计会降低业务风险。好的设计能够充分的兼容日常的问题处理,以及使用过程中的软硬件技术变化。

架构师应该:

  • 抛出系统的架构而隐藏具体的实现
  • 了解所有用例和场景
  • 尽量处理各种不同利益相关者的需求
  • 同时处理功能和质量需求

架构的关键受到用户需求的驱使,而且还受到业务需求的驱使,如更快的结果,更好的支持不同的工作方式和工作流程。

架构设计的原则

当你创建架构设计时考虑下面几个问题:

  • 功能模块中哪些是风险级别最高的?
  • 哪些部分是最可能发生变化的?
  • 你的关键假设是什么,而且你将如何测试他们?
  • 什么情况可能要求你重构你的设计?

不要尝试过度设计,而且不要创造你无法验证的假设。相反,保持你的选择可以兼容可能发生的更改。

关键的架构原则

  • 面向变更设计架构而不是仅面向当前:考虑应用程序在将来可能发生的新的需求变更,然后构建灵活的支持。
  • 进行模型分析并且降低风险:使用设计工具,为系统建模,如UML,从而辅助概括用户需求。
  • 使用模型和图形作为沟通和协作的工具:有效的沟通是好的设计的关键。使用模型、视图或其他架构图形向所有利益相关者表达和分享你的设计。而且还要能够快速的沟通和反应设计的变化。

软件架构的关键概念

CommonApplicationArchitecture

Figure 1
Common application architecture

关键的设计原则

当开始你的设计时,你需要考虑一些原则。这些原则会最小化你的消耗,而且还可以保持对需求的掌握,还可以提高可用性和可扩展性。

这些关键原则包括:

  • 焦点分离:将你的应用程序分割为独立的功能,使他们之间的功能尽可能少的重叠。
  • 单响应原则:每个组件或模块应该仅响应特定的功能。
  • 最少了解原则:一个组件或对象不应该了解另一个组件或对象的内部细节。
  • 不重复原则:你应该仅仅在一个地方定义实现。例如,应用程序设计中,特定的功能应该仅实现在一个组件内;功能不应重复在其他组件中。
  • 尽量避免草率的设计:只进行必要的设计。如果你的应用程序需求不明确,或在将来有对设计进一步进化的可能,那么就需要避免过分早熟的设计。

当设计应用程序或系统时,软件架构的目的是通过将设计分割成不同的关注领域来减少复杂度。例如,UI、业务流程和数据访问分别关注不同的方面。在每个方面中,你设计的组件应该关注特定的内容,而不应该掺入其他领域的代码。例如,UI处理组件就不应该包含直接访问数据源的代码,而是要通过使用业务组件或数据访问组件来获取数据。

设计实践:

  • 保持每层中的设计模式一致:在同一个逻辑层中,组件的设计应该保持一致。例如,如果你选择使用Table Data Gateway模式来创建对象,作为数据库中的表和视图的入口,你就不应该再包含其他设计模式,如Repository。然而,你可能需要使用不同的模式来满足其它需求,如包含业务处理和报表功能的应用程序。
  • 在应用程序中不应出现重复的功能:应该只有一个组件提供一个特定的功能——这个功能也不应该重复出现在其他组件中。这样将会让你的组件更容易优化或变更。重复的功能使变更变得困难,而且也存在着潜在的不一致性。
  • 尽可能使用组合而不是继承:尽可能的使用组合而不是继承来重用功能,因为继承增加了父类和子类之间的依赖,因此限制了子类的重用。
  • 将以一个编码风格和命名规范:你应该建立统一的编码标准。这可以提供一致的模型,使团队成员之间代码变得更容易理解和交流。
  • 在开发过程中使用自动化质量分析技术保持系统的质量:使用单元测试和其他自动化质量分析技术,如依赖分析和静态代码分析。为组件和子系统定义明确的行为和性能指标,然后使用自动化QA工具在编译过程中确保本地设计或实现方法不会对整个系统的质量产生消极的影响。

应用程序分层:

  • 划分不同的区域:将你的应用程序划分成独立的功能区域,使他们之间尽可能少的出现功能重叠。这样做的好处是,每个功能可以分别独立的优化和维护,而不需要依赖与其他功能。另外,如果一个功能失败,它不会导致其它功能也失败,他们可以彼此独立的运行。这个方法还可以使应用程序易于理解和设计,而且有助于管理相互依赖的多个系统。
  • 明确各层之间如何通信:允许每层之间互相通信或层与层之间互相依赖使其构成一个系统,这对理解和管理来说都是挑战。明确规定层之间的依赖关系,才可以保证数据在他们之间顺利流转。
  • 使用抽象来实现层之间的松散耦合:通过定义接口组件,就像一个包含能让大家都知道的对输入和输出请求的格式化组件。另外,你还可以使用接口类型或抽象类类型来定义一个统一的接口或共享的抽象,这些接口类型或抽象类类型必须被接口组件实现。
  • 不要在相同的逻辑层混用不同类型的组件:开始时根据不同的领域识别出了不同的组件,然后就要将这些相关组件分组,这样就形成了逻辑层。例如,UI层不应该包含业务处理组件,但是应该包含处理用户输入或处理用户请求的组件。
  • 在一个层或组件内保持数据格式一致:混乱的数据格式就爱那个会使应用程序更难实现、扩展和管理。每次你需要从一个格式向另一个格式转化数据时,你都需要实现转换代码来执行操作,这样就增加了额外的开支。

组件、模块和功能:

  • 一个组件或对象不应该依赖于另一个组件或对象内部的细节:每个组件或对象应该调用另一个对象或组件的方法,而这个方法应该有一些信息关于如何处理请求。这有助于创建一个更加可维护和可扩展的应用程序。
  • 不要让组件的功能超载:例如,UI处理组件不应该包含数据访问代码或尝试提供额外的功能。超载的组件经常具有很多方法或属性提供业务功能,但是同时却掺杂进了很多额外的功能,如日志和异常处理。应用单响应和分离焦点的原则会有助于改善这种情况。
  • 了解组件之间如何通信:这需要对你的应用程序必须支持的部属场景非常了解。你必须确定如果所有组件运行在同一进程中,还是跨物理或进程边界通信——需要基于消息的接口。
  • 将嵌入的代码从应用程序逻辑中尽可能的抽象出来:嵌入的代码指与安全、通信或操作的管理如日志。将实现这些功能的代码混合在业务逻辑中会导致设计很难被扩展和维护。而对这些嵌入的代码的更改也需要影响所有业务逻辑代码。
  • 为组件定义一个清晰的契约:组件、模块和功能应该定义一个契约或接口来描述他们的用途和行为。契约应该描述其他组件如何访问当前组件、模块或功能内部的方法;而且还应该描述功能中情况发生之前、情况发生之后、异常处理、性能特征等行为。

关键设计考虑

确定应用程序类型

选择适当的应用程序类型是进行应用程序设计的关键部分。你的选择受限于你的特定需求和底层架构的限制。许多应用程序必须支持多种类型的客户端。这里主要讨论以下几个基本应用程序类型:

  • 为移动设备设计的应用程序
  • 主要运行于客户端PC的如客户端应用程序
  • 部属在互联网,支持富用户界面的富互联网应用程序
  • 支持松散耦合组件间通信的服务应用程序
  • 完全连接情况下主要运行在服务器端的Web应用程序

另外还有其他类型的应用程序:

  • 宿主和基于云的应用程序与服务
  • 集成Office和微软服务器技术的Office商业应用程序
  • 提供以门户方式访问商业信息和功能的SharePoint业务线应用程序

确定部属策略

你的应用程序可能部署在各种环境下,每种环境都有它特定的限制,如跨不同服务器的物理隔离的组件、网络协议的限制、防火墙、路由配置等。你必须使用适当的硬件可以支持的模式平衡这些需求。

确定合适的技术

当选择你的应用程序技术时,关键要考虑的是应用程序的类型,以及你将要部属的环境的底层架构。技术选择也会受到组织机制、底层结构、资源技能等等的限制。你必须将你选择的技术与你的应用程序需求相对比,在决定之前设身处地的判断一下这些因素。

确定质量要求

质量要求——如安全、性能和可用性——需要你集中精力来解决这些问题。依赖于你的需求,你可能需要考虑每个质量要求,或仅需要考虑部分就可以。例如,每个应用程序设计必须考虑安全和性能,但是不是每个应用程序都需要考虑互操作性或兼容性。首先要理解你的需求和部属场景,这样才能使你了解质量要求对设计的重要性。同时还要关注质量要求的冲突;例如,安全性要求,通常会影响性能或可用性。

确定潜入的代码的领域

嵌入的代码所表现的领域是你的设计中关键部分。他们不与具体某层相关。例如,你应该考虑实现如下通用解决方案:

  • 日志机制,允许每一层将日志记录到统一的存储位置。
  • 验证和授权机制,来在各层之间传递身份认证信息来分配对资源的访问权限。
  • 异常管理框架也会运行在每一层。
  • 通信方式,你可以用于层与层之间的通讯。
  • 统一缓存架构,允许你缓存持久层、业务层和数据访问层中的数据。
posted on 2011-06-25 18:14  zhangdong  阅读(7624)  评论(0编辑  收藏  举报