Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

软件架构设计基础

24
Oct
2011

软件架构设计基础

By Alex
/ in Architecture
0 Comments
架构简介
什么是架构
微软的观点

架构是一个过程,它定义了满足软件所有操作性、技术性需求的结构化的解决方案。同时对各种质量属性进行优化。

Kruchten的观点

Philippe Kruchten(RUP主管)等人认为,架构是关于软件系统如何组织的一系列重大决定,包括:

  1. 结构元素的识别选择以及它们的对外接口
  2. 行为元素的识别,即上述结构元素之间的协作行为
  3. 上述结构元素、行为元素如何有机结合成为子系统

Philippe Kruchten也认可架构牵涉到易用性、健壮性、性能、可重用性等非功能因素。同时需要兼顾技术性约束和权衡以及美学方面的考虑。

Fowler的观点

企业应用架构模式的作者Martin Fowler总结了当解释何为软件架构时,会反复出现的论点:

  1. 架构将系统进行高层分解,形成多个协作的子系统或者模块
  2. 这种分解决策一旦落地实施,就难以再改变
  3. 一个大型系统中会有多个架构
  4. 在系统的生命周期中,架构可能随着时间而改变,甚至发生重构
  5. 架构可以归结为:软件设计中任何重要的东西
我的观点

尽管有不同的描述方式,软件架构一定牵涉到以下内容:

  1. 系统的结构或者叫组织——将个系统分解为多个组件,分解的粒度不会过细。根据系统的规模不同,可能分解到子系统或者模块级别
  2. 明确分解后系统组件的交互机制
  3. 明确对各种质量需求如何支持,这通常需要引入中间件、框架

用户接口风格设计(例如交互风格、主题和配色)通常不属于系统架构师的职责,但我认为用户接口风格应当在架构阶段即落地。

架构的目标

在决定软件架构时,需要考虑:

  1. 用户如何与软件交互
  2. 软件如何在生产环境下部署和管理
  3. 软件的运行期质量属性,例如性能、并发性、安全性、健壮性、可扩容性、高可用性、易用性
  4. 在软件的生命周期内,开发期质量属性,例如可互操作性、可扩展性、可重用性、可维护性如何保证
  5. 架构的最根本的部分是什么,或者说,哪些决定如果出错后果最严重
  6. 架构的最易变的部分是什么,或者说,哪些决定可以延迟决定
  7. 你做了哪些关键的假设,如何验证这些假设。不要过度设计
  8. 什么情况下,可能导致架构重构

架构的目标:

  1. 暴露系统结构的同时,隐藏实现细节
  2. 实现所有需求用例和应用场景
  3. 满足不同干系人的需求
  4. 同时满足功能需求、质量需求
架构的重要性

为什么要做架构?其根本原因是为了降低复杂性,否则用机器语言可以编写出任何软件。

和其它任何工程一样,软件工程必须具有坚实的基础。对关键场景的错误考虑,对公共模块的错误设计,缺乏对关键决策的长远后果的考虑,都可能对软件工程带来严重的后果。例如:

  1. 软件不能稳定运行
  2. 不能支持现有或者未来的需求
  3. 难以在生产环境下部署和管理

引入中间件、框架,可以减轻构建软件的工作量,但是不能用来代替针对特定应用场景和需求的架构。架构不是一堆框架的糅合。

架构和框架

框架是一种可重用的半成品软件,既然是软件,框架当然可以有自己的架构设计。

框架提供一般性的软件功能,这些功能可以被选择性的覆盖或者扩展,以产生针对性的软件。

框架用于辅助架构的落地,主要用于实现质量需求。在软件实现阶段,框架成为软件的一部分。

架构和设计

架构关注软件中的主要元素和组件如何交互(如何被其它组件或者用户使用)。每个组件的数据结构、算法或者实现细节是详细设计阶段需要考虑的。架构和详设常常重叠。某些情况下,详设具有天然的架构性特征,另外一些情况下,某些重大决策是细致到详设的。

架构原则

前面我们提到过,软件架构(作为名词时)通常被描述为系统的结构或者组织。所谓系统,是完成一个或者多个功能的组件的集合。也就是说,架构需要决定如何来组织组件以满足功能。组件常常基于关注域(areas of concern)进行分组,例如下面的架构图,组件被划分到多个关注域:

common-architecture

分层是解决软件复杂性问题的重要法宝,在上图的例子中,多个关注域构成一个逻辑层,多个逻辑层堆叠形成系统的整体逻辑架构,跨层之间通常不会有交互。

关键设计原则

很多设计原则从实际软件工程的经验教训中总结得到,这些原则不仅仅适用于架构,也适用于详设:

  1. 关注点分离原则:尽可能的把软件划分为多个相互尽可能没有重叠的特性。重要的估量因子是,最小化交互点以实现高内聚低耦合
  2. 单一职责原则:每个组件/模块应当仅仅负责一个特性/功能,或者一个聚合性的功能
  3. 最少知识原则:也叫迪米特法则。一个组件应该尽可能少的知道其它组件的内部细节
  4. 不要重复自己(DRY):一个特定的特性/功能应该仅仅在一个组件中实现,不应在其它组件中重复
  5. 尽可能使用组合而非继承
  6. 不要过度设计:仅仅设计需要的功能。进行前瞻性设计时一定要考虑成本和失败的后果
整体设计
  1. 在每个层内,保持设计模式的一致性
  2. 不要在应用程序里面重复实现一个功能
  3. 创建编码风格和命名规范
分层设计
  1.  将关注域分离到层,应用关注点分离原则。主要好处有:
    1. 一个特性/功能可以独立的被优化
    2. 如果一个特性开发失败,可以被替换而不影响其它特性
    3. 让代码更加容易理解
  2. 明确不同层之间如何交互。通常下层不会依赖上层,不得出现跨层依赖
  3. 基于抽象达到层间松耦合的目标。抽象类、接口、Facade模式都是可用的工具
  4. 不要把不同类型的组件混到一个层中
  5. 在层或组件内保持数据格式的一致性
组件/模块/函数设计
  1. 组件或对象不应依赖其它组件或对象的内部细节,应用最少知识原则
  2. 不要让组件的功能过载,应用单一职责原则。例如UI组件不应该包含数据库访问代码
  3. 理解组件之间的交互方式。要结合部署方式确定,两个组件在进程内、跨进程还是跨机器部署
  4. 尽可能的把横切性的功能从商业逻辑中抽象出去,越远越好。横切性的功能包括身份验证和授权、通信、缓存、日志等
  5. 为组件定义一份清晰的接口规约
关键设计决策
决定应用类型

基本的应用程序类型包括:

  1. 为移动设备设计的应用
  2. 富客户端应用,安装并在客户端PC运行
  3. 富因特网应用,具有丰富的UI组件
  4. 服务型应用,用于支持松耦合的组件的交互
决定部署策略

决定你的应用程序如何部署。各组件是否需要支持跨进程部署,是否需要支持部署在不同的服务器上,这些服务器是否具有网络协议限制、防火墙、路由限制。

部署策略对架构的影响很大,因为需要进程内组件交互可以直接进行函数调用,进程外组件交互必须使用IPC或者Socket等机制。

决定技术框架

最近十多年各领域开源框架大放异彩,因此首先考虑选型开源框架,无法满足需求的情况下才考虑自研。

引入框架后,你的应用程序往往和它产生某种程度上的耦合,因此框架的选择需要慎重。使用框架时,应当尽量避免产生耦合,特别是明确的API调用。

决定质量属性

质量属性聚焦于架构设计需要解决的一系列非功能性的关键问题。根据需求的不同,你需要关注的质量属性也不同。通常每个应用程序都需要关注安全性和性能,但是很多应用程序不需要关注互操作性和可扩容性。

决定横切关注域

横切关注域是不仅仅和某个特定分层有关的关注域。关键的横切关注域包括:

  1. 系统日志:记录系统中各种事件,但不引入敏感信息
  2. 身份验证:决定如何对用户、外部系统的身份进行验证。如何在各层之间传递其身份信息
  3. 访问授权:决定每个层的每个组件能否被指定的实体访问
  4. 异常管理:避免异常信息暴露到最终用户
  5. 通信机制:选择适当的通信协议,最小化网络调用,保证数据安全
  6. 缓存管理:识别哪些数据应该被缓存,在哪里缓存
架构风格

所谓架构风格(Architectural Style,也叫架构模式),是一系列可重用的设计原则, 这些原则以组粒度Pattern的形式定义了一大类系统的抽象框架。你可以认为架构风格是一系列确定了应用系统“形状”的设计原则。

架构风格不会牵涉到具体的技术,因此可以用在技术不可知的技术讨论中。

架构风格可以根据它们的关注域的不同进行分类:

分类 架构风格
通信 SOA、消息总线
部署

客户端/服务器、N-Tier(多层式)、3-Tier、级联、负载均衡、HA

领域 领域驱动设计(DDD)
结构 基于组件的架构、面向对象的架构、分层架构、微服务架构
架构风格摘要
架构风格 说明
客户端/服务器架构 将系统分割为两个独立的应用程序:服务器、客户端。客户端向服务器发起请求
基于组件架构 将应用程序分解为多个可重用的、具有良好接口定义的组件
领域驱动设计 一种面向对象的架构风格,关注如何对商业领域进行建模,并以实体(Entity)的形式在商业领域内对商业对象进行定义
分层架构 将应用程序的关注点分区为堆叠的层 
消息总线  规定中间件系统可以基于一个或者多个通信通道接收、发送消息。这样,通过此中间件交互的组件不需要知道彼此的细节
N-Tier / 3-Tier 类似于分层架构,但是各层部署在不同的物理机器上
面向对象 将应用程序或者系统分解为多个可重用、自包含的对象中。每个对象包含数据和行为
SOA

面向服务架构,也被称为服务化。每个组件基于规约、消息暴露接口,并彼此消费

SOA将系统划分为多个独立运作的服务,相互之间基于中立的接口协议进行交互

SOA的典型实现方式:

  1. WebService,也就是SOAP over HTTP。SOAP是一种基于XML的格式,因此存在不必要的数据冗余
  2. RESTful WebService,常常使用JSON over HTTP
微服务

可以看作是SOA架构的延伸。微服务将系统划分为较细粒度的服务,每个服务都是自治的,通常都有独立的数据存储

微服务允许各系统组件独立的Scale up or down

联用架构风格

一个软件系统几乎不可能仅仅使用一种架构风格。例如,你可能使用SOA架构风格构建服务,同时使用分层架构和面向对象架构。

在开发面向Web的应用系统时,联用架构风格很有意义。使用分层架构风格可以帮助你实现关注点分离,将展现层逻辑和商业逻辑、数据访问逻辑分开。由于组织机构的安全性需求,你可能需要基于3-Tier或者N-Tier架构风格,将展现层部署在周界网络(内外网之间)中。在展现层内部,你可能进一步的应用分层架构风格,典型的是MVC模式。你也可能应用SOA架构风格,让展现层和应用服务器基于消息进行通信。

当构建一个桌面应用时,你可能需要让客户端向某个服务器程序发送请求,这需要C/S架构风格。在服务器端,你可能采用基于组件的架构,将服务器端应用分解为相互独立的组件,让这些组件暴露适当的通信接口。在实现组件时,使用面向对象架构风格可以改善可重用性、易测试性、灵活性。

很多因素会影响架构风格的选择,这些因素包括你的团队开发、设计能力,以及基础设施、组织方面的约束。

客户端/服务器架构风格

这种架构风格描述一种分布式系统,该系统由独立运行的客户端应用和服务器应用组成,服务器和客户端通过网络连接。最简单的C/S架构中服务器和客户端直接通信,也被称为2-Tier架构。

典型的C/S架构客户端是流行在PC上的Native应用,当今浏览器(B/S)、移动设备都可能称为客户端的载体。

C/S架构的变体

C/S架构风格的变体包括:

C/S架构变体 说明
客户端-队列-客户端 允许两个客户端通过服务器端对象进行通信。这种架构允许客户端进行文件和消息的分发。也叫被动队列架构
点对点架构 客户端-队列-客户端架构的升级,允许客户端和服务器互换角色
应用服务器集 服务器作为程序的宿主,瘦客户端发起命令,程序在服务器上执行。典型的例子是SSH这样的Terminal服务
C/S架构的优势
  1. 高安全性:数据存储在服务器上,服务器的安全条件往往远好于客户端
  2. 中心化数据访问:由于数据集中在服务器上,因此管理起来方便
  3. 易于维护:可以实现客户端对服务器的信息的无感知,这样服务器移动、维修、升级会很方便
C/S架构的劣势
  1. 服务器端组件倾向于耦合,导致难以扩展、扩容
  2. 集中性的服务器可能存在单点故障,降低可靠性

为了克服典型C/S架构的缺点,可以引入N-Tier部署架构、负载均衡、HA等

适用场景

当满足以下条件时,可以考虑C/S架构风格:

  1. 你的应用是基于服务器的,且服务器需要支持多个客户端
  2. 你需要创建通过浏览器访问的应用
  3. 你需要开发服务供其它应用程序消费
  4. 你希望集中化数据存储、备份、管理 
基于组件的架构风格

这种架构风格描述了一种系统设计和开发的手段,它关注如何把设计分解为独立的功能、逻辑组件,并且让这些组件暴露出良好定义的通信接口。通信接口的形式可以包含方法、事件、属性。基于组件的架构是面向对象设计原则的一种高层抽象。面向组件架构不关心组件之间的通信协议、共享状态等问题。

组件可能依赖于某种平台提供的环境才能运行,典型的平台包括组件对象模型(COM)、分布式组件模型(DCOM)、通用对象请求代理架构(CORBA)、企业JavaBean(EJB)等等。

依赖注入(DI)、服务定位(Service Locator)之类的设计模式可以用来管理组件之间的依赖,同时降低耦合度、提升可重用度。这类设计模式常常用于构建组合性(Composite)应用程序,以及用于实现跨应用的组件重用。

组件设计原则

基于组件架构的组件设计原则包括:

  1. 可重用性,组件应该可以在不同的场景、不同应用中重用。但是某些组件的确会针对特定项目的特定任务
  2. 可替换性,组件应该很容易被其它类似的组件替换
  3. 上下文无关,组件应该被设计以在不同的上下文中工作。注入状态数据之类的特殊信息应该被传入,而不是保存在组件内
  4. 可扩展性,组件应当允许扩展,以产生新的行为
  5. 封装性,组件暴露接口,其调用者基于接口使用其功能,不应该对外暴露任何内部状态和处理逻辑
  6. 独立性,组件应该尽可能少的依赖其它组件,这样它才能部署到适当的运行环境中,同时不影响其它组件或系统
组件的类型
  1. 用户接口类组件:按钮、表格,这些组件通常被称为控件(Controls)
  2. 助手类组件/实用工具:暴露一些通用的,在其它组件中反复需要的功能
  3. 资源密集型组件:占用资源大,应当以按需(JIT)方式创建。很多远程、分布式组件属于此类型
  4. 排队组件( Queued Components):这些组件的接口可以通过消息队列机制,异步的调用
基于组件架构的优势
  1. 易于部署:当一个新版本的兼容性组件开发完成后,你可以安全的替换老版本的组件,而不会对系统产生影响
  2. 开发成本:使用成熟通用的第三方组件可以降低开发的时间成本
  3. 易于开发:组件暴露良好定义的接口,协作开发时很容易通过Mock实现并行开发
  4. 可重用性:组件往往能够跨越多个系统、项目重用
  5. 降低技术复杂度:通过使用组件容器以及组件容器提供的服务,可以降低使用复杂度。组件容器的服务可以包括组件激活、生命周期管理、方法排队、事件机制、事务性
适用场景

当满足以下条件时,可以考虑基于组件的架构风格:

  1. 你已经拥有合适的组件,或者可以从第三方提供商获得这样的组件
  2. 你的应用程序大量的执行过程式的功能,可能没有或者具有较少的数据输入
  3. 你希望联用基于不同编程语言实现的组件
  4. 你希望实现一个可拔插或者组合性的架构,希望随时能够替换某些组件
领域驱动架构风格

领域驱动设计(DDD)是一种面向对象的软件架构风格。它以业务领域(Business Domain)、业务领域的元素和行为以及这些元素行为之间的关系为基础和依据。

DDD以行业专家(而不是技术专家)的视角来识别、定义(领域)模型,并基于这些模型来组织软件系统,以实现领域的业务逻辑。

要应用DDD,你必须对需要建模的业务领域具有深刻的理解,或者善于获得这些领域的知识。开发团队通常需要和行业专家协同工作。架构师、开发人员、行业专家通常具有不同的知识背景,在很多上下文中他们使用不同的语言描述自己的目标、设计、需求。使用DDD时,所有这些人员使用一种语言来交互,这种语言面向业务领域,不使用技术行话。

基于DDD设计的软件的核心是领域模型,这些模型是上述公共领域语言的直接映射。通过分析公共语言,团队能够快速的发现软件中的Gap。创建公共领域语言不是简单的接受并应用行业专家的知识。开发团队内部的沟通问题不仅仅由于对领域语言的错误理解,也常常由于领域语言本身具有歧义性。DDD过程不仅仅需要创建公共领域语言,更要改善、优化领域语言。这种优化转而能够软件开发收益,因为模型即领域语言的直接映射。

DDD的优势
  1. 沟通:开发团队的所有成员使用领域模型及其定义的实体来针对业务知识进行交流。使用的语言是公共的业务领域语言,而不是技术行话
  2. 可扩展性:领域模型通常是模块化、灵活的。当需求变化后,扩展它们将比较容易
  3. 可测试性:领域模型的对象松耦合、高内聚,这意味着它们便于被测试
适用场景

当满足以下条件时,可以考虑DDD:

  1. 业务领域很复杂,需要有效改善团队的沟通
  2. 你需要基于某种公共语言来向干系人解释你的设计
  3. 你拥有大量复杂的企业级数据场景,难以通过其它技术手段管理它们
分层架构风格

最简单的屏蔽复杂性的途径是引入新的层。

分层架构风格将软件系统中具有相关性的功能分组到一个独立的层中。这些层逐个堆叠,形成类似于栈的结构。每个层内部的功能具有相近的角色或职责。层与层之间的交互是明确定义的、松散耦合的。对应用程序进行分层可以实现关注点的强分离,从而实现灵活性、可维护性。

分层架构风格被描述为倒金字塔式重用。原因是每个层都对它的直接下层的职责和抽象进行了某种聚合。在严格的分层架构中,每个层仅仅能和本层内、直接下层内的组件进行交互。比较自由的分层架构则允许和非直接下层中的组件进行交互。

应用程序的各分层,可能部署在单个服务器中(相同Tier),也可能部署在多台服务器中(N-Tier)。

设计原则
  1. 抽象:分层架构抽象出系统的视图,同时提供足够的细节,让团队能够理解每个层的职责和角色,以及层与层之间的关系
  2. 封装:由于数据类型、方法、属性、实现细节不会在层边界暴露出去,因此在设计时不需要对它们做任何假设
  3. 清晰的层:每个层的功能应当很明确,上层可能向下层发起调用,也可能响应下层发布的事件,这允许上下层之间的数据流动
  4. 高内聚:应当明确每个层的职责边界,确保每个层仅仅包含和它的任务直接相关的功能
  5. 可重用:下层不能对上层产生依赖,这有利于下层的重用
  6. 低耦合:层与层之间的交互应当基于抽象和事件,以降低耦合
消息总线架构风格

消息总线架构风格描述了使用一类中间件系统的原则。这类中间件能够基于多种信道接收、发送消息。这样,以这类中间件作为交互中介的应用程序不需要知道彼此的细节,例如部署位置、使用的通信协议。

最常见的消息总线架构的实现通常基于消息路由器或者订阅/发布系统,通常需要使用到某种消息队列软件。消息总线提供的功能包括:

  1. 面向消息的通信,所有应用以模式(Schema,结构)已知的消息进行通信
  2. 复杂处理逻辑,复杂的操作可以通过一组较小的操作联合而成,每个操作负责特定的任务
  3. 集成不同的环境,基于消息和通用的标准,你可以集成基于不同开发语言的应用,例如Java和.NET

消息总线架构在很多年依赖都用于支持复杂的逻辑处理,它提供了一种可拔插的架构,你可以随时将应用接入到总线以提供新的功能,或者接入统一应用的多个实例以扩容。

消息总线架构的变体包括:

  1. 企业服务总线(ESB):总线和应用以服务的方式进行通信。ESB常常提供消息格式转换的功能,这样使用不兼容消息格式的应用可以通过总线进行互操作
  2. 因特网服务总线(ISB):类似于ESB,但是应用程序在云端而非企业内部网络部署。ISB的核心理念是基于URI的资源定位和消息路由控制策略
消息总线架构的优势
  1. 可扩展性:应用程序可以被添加、移除,现有接入的应用程序不受影响
  2. 低复杂性:每个应用程序仅仅需要和总线直接交互
  3. 灵活性:实现复杂流程的应用程序集、应用程序之间的交互方式,可以根据业务需求轻松的调整。通常只需要调整配置或路由参数
  4. 低耦合:应用程序仅仅暴露了和总线交互的接口,应用程序本身不会相互依赖
  5. 可扩容性:应用程序的多个实例可以连接到总线,以提供更大的处理能力
  6. 简单性:尽管总线本身引入了复杂度,但是对于每个应用程序而言,它仅仅需要和一个总线交互,而不是很多应用程序
适用场景

当满足以下条件时,考虑使用基于总线的架构:

  1. 既有应用程序需要交互以完成特定任务
  2. 需要将多个任务合并为单个操作
N-Tier架构风格

N-Tier是一种部署架构风格,它类似于分层架构,描述了功能的分离方式。被分离的功能可能部署在不同的物理服务器上。这些功能通常使用面向组件的风格设计,使用平台特定的通信手段而非基于消息通信。

典型的N-Tier架构至少具有三个层。例如一个注重安全的Web财务系统,它的业务逻辑层必须部署在防火墙之后,而其展现层则必须部署在周界网络中暴露HTTP端口,客户端则可能运行在因特网上。

N-Tier架构的优势
  1. 可维护性:由于每个Tier相互独立,系统升级不会影响到其它Tier
  2. 可扩容性:可以为某个Tier添加更多的实例实现扩容
  3. 灵活性:每个层可以独立的管理和扩容,因而提高了灵活性
  4. 高可用性:某个Tier可以部署Master/Slave方式的实例,实现HA
面向对象架构风格

这种设计风格将应用程序或者系统划分为单独的可重用、自包含的对象,每个对象包含相关的数据和行为。面向对象的设计将系统看做一系列相互协作的对象,而非一系列例程、过程指令。对象是离散的、独立的、松耦合的,它们通过接口通信。

OO设计原则
  1. 抽象:简化复杂操作为一般化形式,暴露其基本特征
  2. 组合:对象可以相互组装,形成更大的对象。大对象可以隐藏其包含的对象或者为包含对象提供接口
  3. 继承:对象可以从其它对象集成,从而直接获得它的特性
  4. 封装:对象仅仅包含必要的方法、属性、事件,而隐藏大部分细节
  5. 多态:允许在子类中覆盖某些行为
  6. 解耦:通过定义抽象类、接口,使用者可以和对象解耦
面向服务架构风格

SOA风格基于一系列服务对外暴露应用程序的功能,其它的应用程序可以调用这些服务。服务是松散耦合的,因为它们使用基于标准的接口,这些接口可以被调用、发布、发现。SOA中的服务必须以基于消息的、格式(Schema)明确的暴露接口,这些接口是面向应用级别而非面向组件的,具有更粗的粒度。

设计原则
  1. 服务应该是自治的:所有服务应该独立的开发、维护、部署、版本化
  2. 服务应该是分布式的:只要目标网络支持通信协议,服务可以部署在任何网络中,不管是本地还是远程
  3. 服务应该是松耦合的:每个服务不对其它服务产生依赖,只要接口保持兼容,服务可以被替换
  4. 服务共享Schema和规约,而不是类
SOA的优势
  1.  Domain alignment:重用基于标准接口的服务,可以增加商业和技术机会,降低成本
  2. 抽象:服务基于规范化的合约暴露接口,因此了实现细节,因此具有松耦合、抽象性
  3. 可发现:服务可以暴露描述性信息,让其它应用程序能够定位它并自动确定其接口
  4. 互操作性:由于协议、数据格式基于开放工业标准,因此服务提供者、消费者可以基于不同平台开发和部署
适用场景

在以下情况下,可以考虑使用SOA:

  1. 需要重用某个服务
  2. 准备从第三方提供商购买服务
  3. 构建使用多个服务的单一UI应用
  4. 准备构建SaaS平台或者其它基于云的应用
  5. 必须使用平台无关的、基于消息的通信方式
微服务架构风格

使用一系列的微小服务来实现整体的业务流。每个微小服务通常具有专用的数据库、缓存。

每个微服务工作在独立的进程中,可以单独的扩容/缩容,其扩容的自由度比传统粗粒度的SOA更高。微服务常常基于容器技术部署。

每个微服务常常对应了一个全栈的团队,因此跨团队的沟通成本较低。

架构方法
4+1架构视图模型

4+1架构视图模型由Philippe Kruchten提出,基于多种、并发的视角来描述软件密集型系统的架构。这些视角是站在不同干系人角度的,包括最终用户、开发人员、项目管理员。

该模型的4各视图是逻辑架构、开发架构、进程架构、物理架构。此外,典型用例或场景作为+1视图,主要用于架构。

开发架构视图

也叫实现视图(Implementation View),它从程序员的视角来描述系统,项目管理需要关注此视图。可以考虑使用UML的组件图、包图来描述系统的组件及其关系。

逻辑架构视图

从最终用户的角度来描述系统,着重阐述系统包含的功能。UML的类图、状态图可以用于描述逻辑架构。

物理架构视图

也叫部署视图(Deployment View)。从系统工程师的角度来描述系统,关注软件组件的部署拓扑,以及组件之间的物理连接。UML的部署图可以用于描述物理架构。

进程架构视图

关注系统的运行时动态行为,描述系统的进程如何交互。该视图处理并发性、分布性、性能、可扩容性等质量属性。UML的活动图可以用于描述进程架构。

场景视图

通过一小部分关键的业务用例来阐述系统架构。场景视图描述对象、进程之间如何交互。

用户体验

尽管用户体验设计通常不是系统架构设计师的职责范围,但用户体验设计的部分工作的确是“架构”级别的,用户体验设计对易用性、可查找性(Findability)、可访问性等质量属性有重要影响。

架构设计牵涉到四个目标:用户目标、业务目标、系统目标、开发目标的权衡。用户体验设计主要关注如何满足用户目标。

用户体验设计可能影响架构和设计决策,例如:

  1. 为了更实时的UI信息更新,可能导致使用WebSocket作为通信方式
  2. 为了获得更好的用户交互体验,可能需要设计特殊的控件
  3. 为了提升可访问性,引入国际化支持,这需要架构考虑引入新的横切面
什么是UX设计

所谓用户体验,就是指你操作应用程序的UI时的内心感觉。

用户体验设计是通过改善产品的易用性、可访问性,以提高用户满意度的过程。

UX的重要性

最终用户了解软件的唯一途径是和软件的用户接口进行交互,用户体验设计影响用户的第一印象。从心理学角度来说,第一印象非常重要,差劲的用户体验容易让用户对软件甚至是开发商产生刻板印象。
对于产品来说,试用时的用户体验很大程度上影响其采购意愿。

UX设计的内容
视觉设计

也叫图形设计,视觉设计通过色彩、图片、符号等视觉元素向用户传递信息。
视觉设计确定用户接口的美学特性 —— 外观和感觉(Look & Feel)。外观和感觉也即系统的主题(Theme),应当在架构阶段结合用户特点进行确定。

信息架构

所谓信息架构,是指在产品或服务中正确的对信息进行结构化和组织,以提升易用性和可检索性。其工作内容包括:

  1. 导航设计,选择用户接口元素的排列方式。其目标是让用户在信息架构浏览时更加轻松
  2. 结构/组织/标签:
    1. 结构化:化简信息量到它的基本单元,并将这些基本单元关联到一起
    2. 组织:以有意义的方式来分组上述基本单元。例如表单、Grid的行
    3. 标签:使用适当的词汇来支持导航和查找
  3. 查询设计:查询是信息架构中最关键的因素,需要让用户通过检索、询问、浏览等方式获取期望的信息
交互设计

交互设计是用户体验设计的关键。交互设计需要关注的内容是:

  1. 定义在某个上下文中最合适的交互模式
  2. 在研究用户知识特点、使用习惯的过程中确定用户的交互需求
  3. 理解哪些信息和特性对于用户最为重要
  4. 确定用户接口的行为,例如拖拽、选取、鼠标悬停时的行为
  5. 让用户接口尽可能的直观
  6. 在整个系统中保持交互风格的一致性

在过去数年里,交互设计师的职责发生了很大的变化。曾经他们仅仅是确定UI控件及其布局,然后与开发工程师进行确认,现在,交互设计师具有更大的自由度,他们进行面向用户需求的概念性接口设计,而不是首先关心此用户接口能否被实现。

用户体验和质量属性
性能

很明显,性能对用户体验影响很大。性能的三大指标:响应时间、吞吐量、持续高速性,其中响应时间的高低直接影响用户的等待时间。

健壮性

提升系统的健壮性有利于增强用户体验。识别用户的某些输入错误并正确处理,甚至是更正,可以很好的提升用户满意度。反之,用户可能感到困惑,例如某些用户不理解全角、半角数字的区别,在输入全角数字时引发失败会让他不解。

增强此质量属性对传统架构设计的反馈:设计合理的用户输入处理横切面。

易用性

提升易用性很显然会增强用户体验。其方法包括:

  1. 简单的用户接口,界面要尽量的简单,不要让人望而生畏
  2. 缩短响应时间,不要让用户不耐烦的等待。如果等待不可避免,一定要给予合理的提示
  3. 避免用户反感,过多的弹窗、移动应用中过多的推送、角标可能让用户厌烦
  4. 简单清晰的导航,不管导航放在哪里,都要容易找到,易于理解
  5. 理想的配色,符合视觉心理需求的主题和配色。适当的对比度,不要让用户看不清

增强此质量属性对传统架构设计的反馈:

  1. 缩短响应时间,即要求提升性能这一质量属性
可访问性

提升可访问性很显然会提升用户体验,没有此质量属性直接导致部分人群无法使用系统。

可访问性的提升主要牵涉两方面内容:

  1. 国际化,用户支持不同语言背景的用户
  2. 障碍人群支持,包括盲人、色盲、肢体残疾等用户

增强此属性对传统架构设计的反馈:

  1. 要实现国际化,需要通盘考虑,使用消息占位符代替消息文本,可能需要在展现层引入新的子层
  2. 要支持障碍人群,可能需要开发大量功能模块,例如TTS、语音识别 
← Ubuntu知识集锦
日志组件Log4cplus的使用 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 反应器模式
  • 装饰模式
  • 享元模式
  • 服务定位器模式
  • 迭代器模式

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2