系统设计
系统设计
架构设计
软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。
- 词汇表中包含一些构件和连接件类型,
- 而这组约束指出系统是如何将这些构件和连接件组合起来的。
体系结构风格反映了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
经典架构风格
数据流风格
批处理 | 每个处理步骤是一个独立的程序,每一步必须在前一步结束后才能开始, 数据必须是完整的,以整体的方式传递。 它的基本构件是独立的应用程序,连接件是某种类型的媒介 批处理前后构件不一定有关联,但必须前一个行完才能执行下一个 |
经典数据处理、 程序开发、 Windows 下的 BAT 程序 |
管道-过滤器 | 每个构件都有一组输入和输出,构件读输入的数据流,经过内部处理,然后产生输出数据流。 这个过程通常通过对输入流的变换及增量计算来完成,所以在输入被完全消费之前,输出便产生了。 基本构件是过滤器,连接件是数据流传输管道。 |
UNIX shell 编写的程序。 传统的编译器 (包括词法分析、语法分析、语义分析和代码生成) 一个阶段的输出是另一个阶段的输入。 |
两者的区别:
批处理每一个步骤都是独立的,每一步必须在前一步结束后才能开始,数据必须是完整的,以整体的方式传递。
管道过滤器 每个构件都有一组输入和输出,前一个输出作为后一个输入, 数据管道过滤器中流动的这个过程就是对输入流的变换及增量计算 ,在输入被完全消费之前,输出便产生了
调用/返回风格
调用-返回风格在系统中采用了调用与返回机制。利用调用-返回实际上是一种分而治之的策略,主要思想是将一个复杂的大系统分解为若干个子系统,降低复杂度,增加可修改性。
主程序/子程序 | 主程序/子程序风格一般采用单线程控制,把问题划分为若干处理步骤,构件即为主程序和子程序。 子程序通常可合成为模块。过程调用作为交互机制,即充当连接件。 |
|
面向对象 | 面向对象系统风格建立在数据抽象和面向对象的基础上,数据的表示方法和它们的相应操作封装在一个抽象数据类型或对象中。这种风格的构件是对象 | |
层次型 | 每一层为上层服务,并作为下层的接口。仅相邻层间具有层接口, 允许每层用不同的方法实现,为软件重用提供了强大的支持。 连接件由通过层间交互协议来定义 |
以数据为中心
仓库 | 存储和维护数据的中心场所。 由中央数据结构(说明当前数据状态) 和一组独立构件(对中央数据进行操作)组成, 连接件即为仓库与独立构件之间的交互 |
集成IDE |
黑板体 | 是一种问题求解模型,是组织推理步骤、控制状态数据和问题求解之领域知识的概念框架。 黑板系统中,它的这个中心不叫做数据库了,而是黑板,它周围的这些构件儿都叫做知识源。 适合解决没有确定性算法的这一类问题 组成:各种黑板、知识源、控制模块 |
信号处理领域,如语音识别和模式识别 |
独立构件风格
独立构件体系结构风格强调系统中的每个构件都是相对独立的个体,它们之间不直接通信,以降低耦合度,提升灵活度。
进程通信 | 消息传递的方式可以是点到点、异步或同步方式及远程过程调用(RPC)等。 构件是独立的过程,连接件是消息传递。 |
|
事件系统体 | 构件不直接调用一个过程,而是触发或广播一个或多个事件。 系统中的其他构件中的过程在一个或多个事件中注册,当一个事件被触发,系统自动调用在这个事件中注册的所有过程。 |
|
虚拟机风格
虚拟机体系结构风格基本思想是人为构建一个运行环境,可以解析与运行自定义的一些语言,增加架构的灵活性。
解释器 | 通常被用来建立一种虚拟机以弥合程序语义与硬件语义之间的差异 业务灵活组合那就是选择解释器风格。 解释器缺点是执行效率较低。 |
专家系统 用户自行定义游戏对象 |
规则系统体 | 包括知识库、规则解释器、规则/数据选择器及工作内存(程序运行存储区), | 电商促销、AI围棋 |
C2 风格
C2风格通过连接件连接构件或某个构件组,构件与构件之间无连接,

面向服务架构
SOA是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。
SOA 的设计原则
- 无状态。以避免服务请求者依赖于服务提供者的状态。
- 单一实例。避免功能冗余。
- 明确定义的接口。使用者依赖服务规约调用服务,所以服务定义必须长时间稳定,一旦公布,不能随意更改;服务的定义应尽可能明确,减少使用者的不适当使用;不要让使用者看到服务内部的私有数据。
- 自包含和模块化。服务封装了那些在业务上稳定、重复出现的活动和组件,实现服务的功能实体是完全独立自主的,独立进行部署、版本控制、自我管理和恢复。
- 粗粒度。服务数量不应该太大,依靠消息交互而不是远程过程调用(RPC),通常消息量比较大,但是服务之间的交互频度较低。
- 服务之间的松耦合性。服务使用者看到的是服务的接口,其位置、实现技术和当前状态等对使用者是不可见的,服务私有数据对服务使用者是不可见的。
- 重用能力。服务应该是可以重用的。
- 互操作性、兼容和策略声明
SOA 主要协议和规范:
SOAP 简单对象访问协议,Simple Object Access Protocol 。 SOAP是在分散或分布式的环境中交换信息的简单的协议
WSDL :Web服务描述语言,Web Services Description Language , 是一个用来描述Web服务和说明如何与Web服务通信的XML语言。可描述Web服务的三个基本属性。
- 服务做些什么——服务所提供的操作(方法)。
- 如何访问服务——和服务交互的数据格式以及必要协议。
- 服务位于何处——协议相关的地址,如 URL。
UDDI :统一描述、发现和集成,Universal Description Discovery and Integration 。 UDDI 计划是一个广泛的、开放的行业计划,它使得商业实体能够彼此发现;定义它们怎样在Internet上互相作用,并在一个全球的注册体系架构中共享信息。包含了服务描述与发现的标准规范
WSDL用来描述服务,UDDI用来注册和查找服务,而SOAP作为传输层,用来在消费这和服务者之间传送消息
一个消费者可以在UDDI注册表查找服务,取得服务的WSDL描述,然后通过SOAP来调用该服务。企业也可以在UDDI上面注册服务。
服务注册表模式
服务注册表模式,支持如下SOA治理功能:
- 服务注册:应用开发者,也叫服务提供者,向注册表公布他们的功能。他们公布服务合同,包括服务身份、位置、方法、绑定、配置、方案和策略等描述性属性。
- 服务位置:也就是服务应用开发者,帮助他们查询注册服务,寻找符合自身要求的服务。注册表让服务的消费者检索服务合同。对谁可以访问注册表,以及什么服务属性通过注册表暴露的控制
- 服务绑定:服务的消费者利用检索到的服务合同来开发代码,开发的代码将与注册的服务绑定、调用注册的服务以及与它们实现互动。

企业服务总线ESB
其思想是提供一种标准的软件底层架构,各种程序组件能够以服务单元的方式“插入”到该平台上运行,并且组件之间能够以标准的消息通信方式来进行交互。
它的定义通常如下:企业服务总线是由中间件技术实现的支持面向服务架构的基础软件平台,支持异构环境中的服务以基于消息和事件驱动模式的交互,并且具有适当的服务质量和可管理性。
包括:客户端(服务请求者)、基础架构服务(中间件)、核心集成服务(提供服务)。
ESB 的核心功能如下:
- 提供位置透明性的消息路由和寻址服务。
- 提供服务注册和命名的管理功能。
- 支持多种消息传递范型(如请求/响应、发布/订阅等)。
- 支持多种可以广泛使用的传输协议。
- 支持多种数据格式及其相互转换。
- 提供日志和监控功能

一个典型的在 ESB环境中组件之间的交互过程是:( 这种交互过程不再是点对点的直接交互模式,而是由事件驱动的消息交互模式。 )
- 首先由服务请求者触发一次交互过程,产生一个服务请求消息,并将该消息按照ESB 的要求标准化,
- 然后标准化的消息被发送给服务总线。 ESB 根据请求消息中的服务名或者接口名进行目的组件查找,将消息转发至目的组件,并最终将处理结果逆向返回给服务请求者。
通过这种方式, ESB 最大限度上解耦了组件之间的依赖关系,降低了软件系统互连的复杂性。连接在总线上的组件无需了解其他组件和应用系统的位置及交互协议,只需要向服务总线发出请求,消息即可获得所需服务。服务总线事实上实现了组件和应用系统的位置透明和协议透明。技术人员可以通过开发符合 ESB标准的组件(适配器)将外部应用连接至服务总线,实现与其他系统的互操作。同时, ESB 以中间件的方式,提供服务容错、负载均衡、 QoS 保障和可管理功能。
微服务
优点:
- 复杂应用解耦:构将单一模块应用分解为多个微服务,每个服务专注于单一功能。同时保持总体功能不变。避免了复杂度的不断积累
- 独立 每个微服务可进行独立开发与部署,某个微服务发生变更时无需编译、部署整个系统应用
- 技术选型灵活 每个开发团队可根据自身应用的业务需求发展状况选择合适的体系架构与技术
- 容错 在微服务架构下,由于各个微服务相互独立,故障会被隔离在单个服务中,不会造成全局应用系统瘫痪
- 松耦合,易扩展 微服务架构中每个服务之间都是松耦合的,可以根据实际需求实现独立扩展,体现微服务架构的灵活性
微服务架构面临的问题与挑战
- 微服务架构的分区数据库体系,不同服务拥有不同数据库,不得不放弃传统数据库的强一致性,转而追求最终一致性、
- 服务发现与服务调用链跟踪变得困难
- 性能问题:由于微服务注重独立性,互相通信时只能通过标准接口,可能产生延迟或调用出错。
MDA
MDA的3种核心模型:
- 平台独立模型(PIM) 【平台无关模型】:具有高抽象层次、独立于任何实现技术的模型。
- 平台相关模型(PSM)【平台相关模型】:为某种特定实现技术量身定做,让你用这种技术中可用的实现构造来描述系统的模型。PIM会被变换成一个或多个PSM。
- 代码Code:用源代码对系统的描述(规约)。每个PSM都将被变换成代码。
架构评估
业界已开发出多种软件架构评估的方法,按基于的技术手段来看,可以分为三类:基于调查问卷或检查表的方式、基于场景的方式和基于度量的方式。
基于调查问卷或检查表的方式:该方式的关键是要设计好问卷或检查表,它充分利用系统相关人员的经验和知识,获得对架构的评估。其缺点是在很大程度上依赖于评估人员的主观推断。
基于度量的方式:制定一些定量值来度量架构,如代码行数等。要制定质量属性和度量结果之间的映射
基于场景的方式 : 包括架构权衡分析法(Architecture Tradeoff Analysis Method,ATAM)和软件架构分析方法(Software Architecture Analysis Method,SAAM),以及CBAM(Cost Benefit Analysis Method)成本收益分析方法。通过分析软件架构对场景(也就是对系统的使用或修改活动)的支持程度,从而判断该架构对这一场景所代表的质量需求的满足程度。
场景
- 刺激源:谁造成的刺激
- 刺激:一个响应系统的情况
- 制品:系统被刺激的部分
- 环境:刺激发生时,系统所处的状态
- 响应:刺激所产生的结果
- 响应度量指标:如何评估响应

SAAM、ATAM
SAAM | ATAM ( 架构权衡分析方法 ) | CBAM ( 成本收益分析方法 ) | |
---|---|---|---|
描述 | 最初它用于比较不同软件体系的架构,以分析系统架构的可修改性,后来实践证明它也可用于其他质量属性 | 是 在SAAM 的基础上发展起来的,主要针对性能、实用性、安全性和可修改性,在系统开发之前,对这些质量属性进行评价和折中 | CBAM 用来对架构设计决策的成本和收益进行建模,它的基本思想是架构策略影响系统的质量属性,反过来这些质量属性又会为系统的项睦干系人带来一些收益(称为“效 用 ”) |
特定目标 | SAAM 的目标是对描述应用程序属性的文档,验证基本的架构假设和原则 | ATAM 的目标是在考虑多个相互影响的质量属性的情况下,从原则上提供一种理解软件架构的能力的方法 | 在 ATAM 评估结果的基础上对架构的经济性进行评估 |
活动 | 形成场景、架构描述、 对场景的分类和确定优 、单个场景评估、评估场景交互作用、 总体评估 | 场景和需求收集、架构视图和场景实现、属性模型构造和分析、折中 | 整理场景、对场景进行细化、确定场景优先级、分配效用、 确定期望的质量属性响应级别的效用、 计算各架构策略的总收益、 根据受成本限制影响的投资收益率选择架构策略 |
评估技术 | 场景技术 | 场景技术 | 场景技术 |
质量属性 | 可修改性是 SAAM 分析的主要质量属性 | 分析多个相互竞争的质量属性 | 经济性进 |

处理流程设计
工作流管理系统
工作流管理系统(Work Flow Management System,WFMS)通过软件定义、创建工作流并管理其执行
WFMS 的基本功能
- 对工作流进行建模。即定义工作流,包括具体的活动和规则等,所创建的模型是同时可以被人和计算机所“理解”的,工作流对应现实世界的业务处理过程,不能改变真实业务的处理逻辑。
- 工作流执行。遵循工作流模型来创建和执行实际的工作流,即通过WFMS 可以执行多个工作项。
- 业务过程的管理和分析。监控和管理执行中的业务(工作流),例如,进度完成情况和数据所处状态、工作分配与均衡情况等。
工作流参考模型(Work flow Reference Model , WRM ) 包含 6 个基本模块,分别是
- 工作流执行服务: 【核心模块】,功能包括【创建和管理流程定义】,创建、管理和执行流程实例。
- 工作流引擎:是为流程实例【提供运行环境】,并解释执行流程实例的软件模块。
- 流程定义工具:是【管理流程定义的工具】,它可以通过图形方式把复杂的流程定义显示出来并加以操作,流程定义工具与工作流执行服务交互,一般该模块为设计人员提供图形化的用户界面。
- 客户端应用:是通过请求的方式与工作流执行服务交互的应用。
- 调用应用:是【被工作流执行服务调用的应用】,调用应用与工作流执行服务交互。
- 管理监控工具:主要指组织机构和参与者等数据的维护管理和流程执行情况的监控,管理监控工具与工作流执行服务交互。
、
流程设计工具
程序流程图
程序流程图(Program Flow Diagram,PFD ) 用一些图框表示各种操作,它独立于任何一种程序设计语言,比较直观、清晰,易于学习掌握。流程图中只能包括图13-2所示的 5 种基本控制结构,任何复杂的程序流程图都应由这5 种基本控制结构组合或嵌套而成。

N-S图
用方框代替传统的程序流程图(PFD)。
在 N-S 图中也包括5 种控制结构,分别是顺序型、选择型、 WHILE 循环型(当型循环)、UNTIL 循环型(直到型循环)和多分支选择型

问题分析图
问题分析图(Problem Analysis Diagram,PAD ) 是继PFD 和 N -S 图之后,又一种描述详细设计的工具,它由日立公司于1979年提出,也是一种支持结构化程序设计的图形工具。PAD 也包含 5 种基本控制结构,并允许递归使用

IPO图
IPO图用来描述每个模块的输入、输出和数据加工

结构化设计
概要设计、详细设计
结构化设计(Structured Design , 以下简称SD ) 是一种面向数据流的方法,它以SRS 代表的软件需求规格说明(Software Requirements Specification), SA 代表的系统分析(System Analysis)阶段所产生的数据流图和数据字典等文档为基础,是一个自顶向下、逐步求精和模块化的过程。SD 方法的基本思想是将软件设计成由相对独立且具有单一功能的模块组成的结构,分为概要设计和详细设计两个阶段
概要设计又称为系统总体结构设计,它是系统开发过程中很关键的一步,其主要任务是将系统的功能需求分配给软件模块,确定每个模块的功能和调用关系,形成软件的模块结构图,即系统结构图。在概要设计中,将系统开发的总任务分解成许多个基本的、具体的任务。确定每个模块的功能、接口和模块之间的调用关系
详细设计:为每个具体任务选择适当的技术手段和处理方法 ,为每个模块设计实现的细节
模块的四个要素:
输入和输出:模块的输入来源和输出去向都是同一个调用者,即一个模块从调用者那儿取得输入,进行加工后再把输出返回调用者
处理功能:指模块把输入转换成输出所做的工作。
内部数据:指仅供该模块本身引用的数据。
程序代码:指用来实现模块功能的程序。
结构化设计原则
模块独立性原则 ( 高内聚、低耦合)
保持模块的大小适中
扇入/扇出系数合理 (多扇入,少扇出)
- 扇出表示调用了其他模块,扇出越多,表示模块复杂度越高,耦合度越高。
- 扇入表示被几个模块调用,扇入越多,表示模块的复用做的越好
深度和宽度均不宜过高

内聚类型 | 描 述 | |
---|---|---|
功能内聚 | 完成一个单一功能,各个部分协同工作,缺一不可 | |
顺序内聚 | 处理元素相关,而且必须顺序执行 | |
通信内聚 | 所有处理元素集中在一个数据结构的区域上 | 类 |
过程内聚 | 处理元素相关,而且必须按特定的次序执行 | 强调的是 特定的序列,可以不是顺序 |
瞬时内聚(时间内聚) | 所包含的任务必须在同一时间间隔内执行 | 变量初始化 |
逻辑内聚 | 完成逻辑上相关的一组任务 | 把一件事情的各个流程合并成一个大的模块。 例如:把添加购物车、提交订单、付款等几个步骤合并成“购物”模块 |
偶然内聚(巧合内聚) | 完成一组没有关系或松散关系的任务 |
耦合类型 | 描 述 | |
---|---|---|
非直接耦合 | 两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的 | |
数据耦合 | —组模块借助参数表传递简单数据 | |
标记耦合 | —组模块通过参数表传递记录信息 ( 数据结构) | |
控制耦合 | 模块之间传递的信息中包含用于控制模块内部逻辑的信息 | |
外部耦合 | 一组模块都访问同一全局简单变量, 而且不是通过参数表传递该全局变量的信息 | |
公共耦合 | 多个模块都访问同一个公共数据环境 | |
内部耦合 | 一个模块直接访问另一个模块的内部 ; 两个模块有一部分程序代码重叠 一个模块不通过正常入口转到另一个模块的内部 一 个模块有多个入 口 |
面向对象设计
设计软件类
在系统设计过程中,类可以分为三种类型:实体类、边界类和控制类
实体类映射需求中的每个实体,实体类保存需要存储在永久存储体中的信息
控制类是用于控制用例工作的类
- 应用逻辑、业务逻辑、数据处理逻辑
- “动词+名词”或 “名 词+动词” 例如:身份验证器
边界类用于封装在用例内、外流动的信息或数据流
- 窗体、报表、打印机和扫描仪等硬件的接口
- 菜单、购物车、报表、二维码
- 窗口、通信协议、打印机接口、传感器和终端
面向对象设计的原则
单一职责原则:设计目的单一的类
开放-封闭原则:对扩展开放,对修改封闭
里氏(Liskov)替换原则:子类可以替换父类
依赖倒置原则:要依赖于抽象,而不是具体实现;针对接口编程,不要针对实现编程
接口隔离原则:使用多个专门的接口比使用单一的总接口要好
组合重用原则:要尽量使用组合,而不是继承关系达到重用目的
迪米特(Demeter)原则、最少知识原则 :一个对象应当对其他对象有尽可能少的了解