快速指南
软件架构与设计简介
系统的架构描述了它的主要组件、它们的关系(结构)以及它们如何相互作用。软件架构和设计包括几个影响因素,例如业务策略、质量属性、人员动态、设计和 IT 环境。
我们可以将软件架构和设计分为两个不同的阶段:软件架构和软件设计。在架构中,非功能性决策是由功能性需求决定和分离的。在设计中,功能需求得以实现。
软件架构
架构充当系统的蓝图。它提供了一个抽象来管理系统复杂性并在组件之间建立通信和协调机制。
它定义了一个结构化解决方案,以满足所有技术和操作要求,同时优化性能和安全性等常见质量属性。
此外,它还涉及与软件开发相关的组织的一系列重要决策,其中每个决策都可能对最终产品的质量、可维护性、性能和整体成功产生相当大的影响。这些决定包括 -
选择组成系统的结构元素及其接口。
这些元素之间的协作中指定的Behave。
将这些结构和Behave元素组合成大型子系统。
架构决策与业务目标保持一致。
架构风格指导组织。
软件设计
软件设计提供了一个设计计划,该计划描述了系统的元素、它们如何配合以及如何协同工作来满足系统的要求。制定设计计划的目标如下:
与客户、营销和管理人员协商系统要求并设定期望。
在开发过程中充当蓝图。
指导实施任务,包括详细设计、编码、集成和测试。
它发生在详细设计、编码、集成和测试之前,领域分析、需求分析和风险分析之后。
建筑的目标
架构的主要目标是确定影响应用程序结构的需求。精心设计的架构可以降低与构建技术解决方案相关的业务风险,并在业务和技术需求之间架起一座桥梁。
一些其他目标如下 -
暴露系统的结构,但隐藏其实现细节。
实现所有用例和场景。
尝试满足不同利益相关者的要求。
处理功能和质量要求。
减少所有权目标并提高组织的市场地位。
提高系统提供的质量和功能。
提高外部对组织或系统的信心。
局限性
软件架构仍然是软件工程中的一个新兴学科。它有以下限制 -
缺乏表示架构的工具和标准化方法。
缺乏分析方法来预测架构是否会产生满足要求的实现。
缺乏对架构设计对软件开发重要性的认识。
对软件架构师的角色缺乏了解,利益相关者之间的沟通不畅。
缺乏对设计流程的了解、设计经验和设计评价。
软件架构师的角色
软件架构师提供技术团队可以为整个应用程序创建和设计的解决方案。软件架构师应具备以下领域的专业知识 -
设计专长
软件设计专家,包括面向对象设计、事件驱动设计等多种方法和途径。
领导开发团队并协调开发工作以确保设计的完整性。
应该能够审查设计方案和它们之间的权衡。
领域专业知识
正在开发的系统和软件发展规划方面的专家。
协助需求调查过程,确保完整性和一致性。
协调正在开发的系统的领域模型的定义。
技术专长
有助于系统实施的可用技术专家。
协调编程语言、框架、平台、数据库等的选择。
方法论专业知识
SDLC(软件开发生命周期)期间可能采用的软件开发方法方面的专家。
选择对整个团队有帮助的适当的开发方法。
软件架构师的隐藏角色
促进团队成员之间的技术工作并加强团队中的信任关系。
分享知识并拥有丰富经验的信息专家。
保护团队成员免受外部力量的影响,这些外部力量会分散他们的注意力并给项目带来更少的价值。
建筑师的交付成果
一套清晰、完整、一致且可实现的功能目标
系统的功能描述,至少有两层分解
系统的概念
系统形式的设计,至少有两层分解
时间安排、操作员属性以及实施和操作计划的概念
确保遵循功能分解并控制接口形式的文档或流程
质量属性
质量是对卓越性或没有缺陷或缺陷的状态的衡量。质量属性是独立于系统功能的系统属性。
实施质量属性可以更轻松地区分好系统和坏系统。属性是影响运行时Behave、系统设计和用户体验的总体因素。
它们可以分类为 -
静态质量属性
反映系统和组织的结构,与架构、设计和源代码直接相关。它们对最终用户来说是不可见的,但会影响开发和维护成本,例如:模块化、可测试性、可维护性等。
动态质量属性
反映系统在执行过程中的Behave。它们与系统的架构、设计、源代码、配置、部署参数、环境和平台直接相关。
它们对最终用户可见并在运行时存在,例如吞吐量、鲁棒性、可扩展性等。
质量场景
质量场景指定如何防止故障变成故障。根据其属性规格,它们可以分为六个部分 -
源- 产生刺激的内部或外部实体,例如人员、硬件、软件或物理基础设施。
刺激- 当它到达系统时需要考虑的条件。
环境- 刺激发生在某些条件下。
工件- 整个系统或其中的某些部分,例如处理器、通信通道、持久存储、进程等。
响应- 刺激到达后进行的活动,例如检测故障、从故障中恢复、禁用事件源等。
响应措施- 应测量发生的响应,以便测试需求。
通用质量属性
下表列出了软件架构必须具有的常见质量属性 -
类别 | 质量属性 | 描述 |
---|---|---|
设计品质 | 概念完整性 | 定义整体设计的一致性和连贯性。这包括组件或模块的设计方式。 |
可维护性 | 系统能够在一定程度上轻松地进行更改。 | |
可重复使用性 | 定义组件和子系统适合在其他应用程序中使用的功能。 | |
运行时质量 | 互操作性 | 一个系统或不同系统通过与外部方编写和运行的其他外部系统进行通信和交换信息来成功运行的能力。 |
可管理性 | 定义系统管理员管理应用程序的难易程度。 | |
可靠性 | 系统随着时间的推移保持运行的能力。 | |
可扩展性 | 系统在不影响系统性能的情况下处理负载增加的能力或易于扩展的能力。 | |
安全 | 系统防止超出设计用途的恶意或意外操作的能力。 | |
表现 | 指示系统在给定时间间隔内执行任何操作的响应能力。 | |
可用性 | 定义系统正常运行的时间比例。它可以以预定义时间段内总系统停机时间的百分比来衡量。 | |
系统质量 | 支持性 | 系统在无法正常工作时提供有助于识别和解决问题的信息的能力。 |
可测试性 | 衡量为系统及其组件创建测试标准的难易程度。 | |
用户素质 | 可用性 | 定义应用程序通过直观满足用户和消费者需求的程度。 |
建筑质量 | 正确性 | 满足系统所有要求的责任。 |
非运行时质量 | 可移植性 | 系统在不同计算环境下运行的能力。 |
完整性 | 能够使单独开发的系统组件正确地协同工作。 | |
可修改性 | 每个软件系统都可以轻松地适应其软件的更改。 | |
业务质量属性 | 成本和时间表 | 系统成本与上市时间、预期项目寿命和遗留资源的利用有关。 |
适销性 | 使用与市场竞争相关的系统。 |
关键原则
软件架构被描述为系统的组织,其中系统代表一组完成定义功能的组件。
建筑风格
架构风格,也称为架构模式,是一组塑造应用程序的原则。它从结构组织模式的角度定义了一个系统族的抽象框架。
建筑风格负责 -
提供组件和连接器的词典以及如何组合它们的规则。
通过为经常出现的问题提供解决方案来改进分区并允许重用设计。
描述配置组件集合(具有明确定义的接口、可重用和可替换的模块)和连接器(模块之间的通信链路)的特定方法。
为基于计算机的系统构建的软件表现出多种架构风格之一。每种风格都描述了一个系统类别,其中包括 -
执行系统所需功能的一组组件类型。
一组连接器(子例程调用、远程过程调用、数据流和套接字),可实现不同组件之间的通信、协调和协作。
语义约束定义了如何集成组件以形成系统。
组件的拓扑布局表明它们运行时的相互关系。
通用建筑设计
下表列出了可以按其重点关注领域组织的架构风格 -
类别 | 建筑设计 | 描述 |
---|---|---|
沟通 | 消息总线 | 规定了可以使用一个或多个通信通道接收和发送消息的软件系统的使用。 |
面向服务的架构 (SOA) | 定义使用契约和消息将功能作为服务公开和使用的应用程序。 | |
部署 | 客户端服务器 | 将系统分为两个应用程序,客户端向服务器发出请求。 |
3 层或 N 层 | 将功能分成单独的部分,每个部分都是位于物理上独立的计算机上的一层。 | |
领域 | 领域驱动设计 | 专注于对业务域进行建模并基于业务域内的实体定义业务对象。 |
结构 | 基于组件 | 将应用程序设计分解为可重用的功能或逻辑组件,这些组件公开定义良好的通信接口。 |
分层 | 将应用程序的关注点划分为堆叠组(层)。 | |
面向对象 | 基于将应用程序或系统的职责划分为对象,每个对象包含与该对象相关的数据和Behave。 |
建筑类型
从企业的角度来看,有四种类型的架构,这些架构统称为企业架构。
业务架构- 定义企业内的业务、治理、组织和关键业务流程的策略,并重点关注业务流程的分析和设计。
应用程序(软件)架构- 充当各个应用程序系统、它们的交互以及它们与组织业务流程的关系的蓝图。
信息架构- 定义逻辑和物理数据资产以及数据管理资源。
信息技术 (IT) 架构- 定义构成组织整体信息系统的硬件和软件构建块。
架构设计流程
架构设计过程的重点是将系统分解为不同的组件及其交互,以满足功能和非功能需求。软件架构设计的关键输入是 -
分析任务产生的需求。
硬件架构(软件架构师又向系统架构师提供需求,系统架构师配置硬件架构)。
架构设计过程的结果或输出是架构描述。基本架构设计过程由以下步骤组成 -
了解问题
这是最关键的一步,因为它会影响后续设计的质量。
如果没有清楚地了解问题,就不可能创建有效的解决方案。
许多软件项目和产品被认为是失败的,因为它们实际上没有解决有效的业务问题或没有可识别的投资回报(ROI)。
确定设计元素及其关系
在此阶段,构建用于定义系统边界和上下文的基线。
根据功能需求将系统分解为其主要组件。可以使用设计结构矩阵 (DSM) 对分解进行建模,该矩阵显示设计元素之间的依赖关系,而无需指定元素的粒度。
在此步骤中,架构的第一次验证是通过描述多个系统实例来完成的,此步骤称为基于功能的架构设计。
评估架构设计
每个质量属性都会给出一个估计值,以便收集定性测量或定量数据,对设计进行评估。
它涉及评估架构是否符合架构质量属性要求。
如果所有估计的质量属性都符合要求的标准,则架构设计过程就完成了。
如果没有,则进入软件架构设计的第三阶段:架构转型。如果观察到的质量属性不满足其要求,则必须创建新的设计。
转变架构设计
此步骤是在评估架构设计后执行的。必须更改架构设计,直到完全满足质量属性要求。
它涉及选择设计解决方案以提高质量属性,同时保留域功能。
通过应用设计运算符、样式或模式来转换设计。改造时,采用现有设计,应用分解、复制、压缩、抽象、资源共享等设计算子。
再次评估设计,如有必要,相同的过程会重复多次,甚至递归执行。
转换(即质量属性优化解决方案)通常会改善一种或某些质量属性,同时对其他质量属性产生负面影响
关键架构原则
以下是设计架构时要考虑的关键原则 -
构建变革而不是构建基业长青
考虑应用程序可能需要如何随着时间的推移而改变,以应对新的需求和挑战,并建立灵活性来支持这一点。
降低风险和模型进行分析
使用设计工具、可视化、建模系统(例如 UML)来捕获需求和设计决策。还可以分析影响。不要将模型形式化到抑制轻松迭代和调整设计的能力的程度。
使用模型和可视化作为沟通和协作工具
设计、决策和设计的持续变更的有效沟通对于良好的架构至关重要。使用架构的模型、视图和其他可视化效果与所有利益相关者有效地沟通和共享设计。这使得能够快速传达设计变更。
识别并了解关键的工程决策以及最常犯错误的领域。投资于第一次就做出正确的关键决策,以使设计更加灵活,并且不太可能因变化而被破坏。
使用增量和迭代方法
从基线架构开始,然后通过迭代测试改进候选架构以改进架构。通过多次迭代向设计添加细节,以获得整体或正确的图片,然后专注于细节。
主要设计原则
以下是最小化成本、维护要求以及最大化架构的可扩展性和可用性时要考虑的设计原则 -
关注点分离
将系统的组件划分为特定的功能,以便组件功能之间不存在重叠。这将提供高内聚和低耦合。这种方法避免了系统组件之间的相互依赖,有助于轻松维护系统。
单一责任原则
系统的每个模块都应该有一个特定的职责,这有助于用户清楚地了解系统。它还应该有助于该组件与其他组件的集成。
最少知识原则
任何组件或对象都不应该了解其他组件的内部细节。这种方法避免了相互依赖并有助于可维护性。
最大限度地减少前期大型设计
如果应用程序的要求不清楚,请尽量减少前期的大型设计。如果有可能修改需求,那么就避免对整个系统进行大型设计。
不要重复功能
不重复功能指定组件的功能不应重复,因此一段代码应仅在一个组件中实现。应用程序中的功能重复可能会导致难以实施更改、降低清晰度并引入潜在的不一致。
在重用功能时更喜欢组合而不是继承
继承在子类和父类之间创建了依赖关系,因此它阻止了子类的自由使用。相反,组合提供了很大程度的自由并减少了继承层次结构。
识别组件并将它们分组到逻辑层中
系统中满足要求所需的身份组件和关注领域。然后将这些相关组件分组在一个逻辑层中,这将有助于用户在较高层次上理解系统的结构。避免在同一层中混合不同类型关注点的组件。
定义层间通信协议
了解组件如何相互通信,这需要全面了解部署场景和生产环境。
定义图层的数据格式
各个组件将通过数据格式相互交互。不要混合数据格式,以便应用程序易于实现、扩展和维护。尽量保持同一层的数据格式相同,以便各个组件在相互通信时不需要对数据进行编码/解码。它减少了处理开销。
系统服务组件应该是抽象的
与安全、通信或系统服务(例如日志记录、分析和配置)相关的代码应抽象在单独的组件中。不要将此代码与业务逻辑混合,因为它很容易扩展设计和维护它。
设计异常及异常处理机制
提前定义异常可以帮助组件以优雅的方式管理错误或不需要的情况。整个系统的异常管理将是相同的。
命名约定
应提前定义命名约定。它们提供了一致的模型,帮助用户轻松理解系统。团队成员更容易验证其他人编写的代码,因此会提高可维护性。
架构模型
软件架构涉及软件系统抽象的高层结构,通过分解和组合,具有架构风格和质量属性。软件架构设计必须符合系统的主要功能和性能需求,同时满足可靠性、可扩展性、可移植性、可用性等非功能性需求。
软件架构必须描述其组件组、它们的连接、它们之间的交互以及所有组件的部署配置。
软件架构可以通过多种方式定义 -
UML(统一建模语言) - UML 是软件建模和设计中使用的面向对象的解决方案之一。
架构视图模型(4+1视图模型) - 架构视图模型代表软件应用程序的功能和非功能需求。
ADL(架构描述语言) - ADL 在形式上和语义上定义了软件架构。
统一建模语言
UML 代表统一建模语言。它是一种用于制作软件蓝图的图形语言。UML 由对象管理组 (OMG) 创建。UML 1.0 规范草案于 1997 年 1 月向 OMG 提出。它作为软件需求分析和设计文档的标准,是开发软件的基础。
UML 可以被描述为一种通用的可视化建模语言,用于可视化、指定、构造和记录软件系统。尽管UML通常用于对软件系统进行建模,但它并不限于此范围。它还用于对非软件系统进行建模,例如制造单元中的流程。
这些元素就像组件一样,可以通过不同的方式关联起来形成完整的 UML 图片,即所谓的图表。因此,理解不同的图表以在现实系统中实现知识非常重要。我们有两大类图表,它们进一步分为子类别,即结构图和Behave图。
结构图
结构图表示系统的静态方面。这些静态方面代表了图表中形成主要结构的部分,因此是稳定的。
这些静态部分由类、接口、对象、组件和节点表示。结构图可以细分如下 -
- 类图
- 对象图
- 元件图
- 部署图
- 封装图
- 复合结构
下表提供了这些图的简要说明 -
先生。 | 图表及说明 |
---|---|
1 |
班级 代表系统的面向对象。显示类如何静态相关。 |
2 |
目的 表示运行时的一组对象及其关系,也表示系统的静态视图。 |
3 |
成分 描述系统的所有组件、它们的相互关系、交互和接口。 |
4 |
复合结构 描述组件的内部结构,包括组件的所有类、接口等。 |
5 |
包裹 描述包结构和组织。涵盖包中的类以及另一个包中的包。 |
6 |
部署 部署图是一组节点及其关系。这些节点是部署组件的物理实体。 |
Behave图
Behave图基本上捕获了系统的动态方面。动态方面基本上是系统的变化/移动部分。UML 有以下类型的Behave图 -
- 用例图
- 时序图
- 通讯图
- 状态图图
- 活动图
- 交互概览
- 时序图
下表提供了这些图的简要说明 -
先生。 | 图表及说明 |
---|---|
1 |
使用案例 描述功能及其内部/外部控制器之间的关系。这些控制器称为参与者。 |
2 |
活动 描述系统中的控制流程。它由活动和链接组成。该流程可以是顺序的、并发的或分支的。 |
3 |
状态机/状态图 表示系统的事件驱动状态变化。它基本上描述了类、接口等的状态变化。用于可视化系统通过内部/外部因素的反应。 |
4 |
顺序 可视化系统中执行特定功能的调用序列。 |
5 |
交互概述 结合活动图和序列图来提供系统和业务流程的控制流概述。 |
6 |
沟通 与序列图相同,只是它侧重于对象的角色。每个通信都与序列顺序、编号加上过去的消息相关联。 |
7 |
时间顺序 通过消息描述状态、条件和事件的变化。 |
架构视图模型
模型是对软件架构的完整、基本和简化的描述,它由特定角度或观点的多个视图组成。
视图是从一组相关关注点的角度对整个系统的表示。它用于从不同利益相关者(例如最终用户、开发人员、项目经理和测试人员)的角度来描述系统。
4+1视图模型
4+1 视图模型由 Philippe Kruchten 设计,用于描述基于使用多个并发视图的软件密集型系统的体系结构。它是一个多视图模型,可以解决系统的不同功能和问题。它标准化了软件设计文档,并使所有利益相关者易于理解设计。
它是一种用于研究和记录软件架构设计的架构验证方法,涵盖了所有利益相关者的软件架构的所有方面。它提供了四个基本观点 -
逻辑视图或概念视图- 它描述了设计的对象模型。
流程视图- 它描述系统的活动,捕获设计的并发和同步方面。
物理视图- 它描述了软件到硬件的映射并反映了其分布式方面。
开发视图- 它描述了软件在其开发环境中的静态组织或结构。
可以通过为软件系统的最终用户或客户添加一个称为场景视图或用例视图的视图来扩展此视图模型。它与其他四个视图一致,用于说明充当“加一”视图(4+1)视图模型的架构。下图描述了采用五并发视图(4+1)模型的软件架构。
为什么叫4+1而不是5呢?
用例视图具有特殊的意义,因为它详细说明了系统的高级需求,而其他视图则详细说明了如何实现这些需求。当所有其他四个视图都完成后,它实际上是多余的。然而,没有它,所有其他观点都是不可能的。下图和表格详细显示了 4+1 视图 -
逻辑性 | 过程 | 发展 | 身体的 | 设想 | |
---|---|---|---|---|---|
描述 | 显示系统的组件(对象)以及它们的交互 | 显示系统的进程/工作流规则以及这些进程如何通信,重点关注系统的动态视图 | 给出系统的构建块视图并描述系统模块的静态组织 | 显示软件应用程序的安装、配置和部署 | 通过执行验证和插图显示设计已完成 |
观众/利益相关者 | 最终用户、分析师和设计师 | 集成商和开发商 | 程序员和软件项目经理 | 系统工程师、操作员、系统管理员和系统安装人员 | 他们的观点和评估者的所有观点 |
考虑 | 功能要求 | 非功能性需求 | 软件模块组织(软件管理重用、工具约束) | 有关底层硬件的非功能性需求 | 系统一致性和有效性 |
UML – 图表 | 类、状态、对象、序列、通信图 | 活动图 | 元件、封装图 | 部署图 | 用例图 |
架构描述语言 (ADL)
ADL 是一种提供用于定义软件架构的语法和语义的语言。它是一种符号规范,提供了对软件系统概念架构进行建模的功能,与系统的实现不同。
ADL 必须支持架构组件、它们的连接、接口和配置,它们是架构描述的构建块。它是一种用于架构描述的表达形式,提供分解组件、组合组件和定义组件接口的能力。
架构描述语言是一种形式化的规范语言,它描述了进程、线程、数据、子程序等软件特征以及处理器、设备、总线、内存等硬件组件。
很难对 ADL 和编程语言或建模语言进行分类或区分。但是,将语言归类为 ADL 需要满足以下要求 -
它应该适合于将架构传达给所有相关方。
它应该适合架构创建、细化和验证的任务。
它应该为进一步的实现提供基础,因此它必须能够向ADL规范添加信息,使得最终的系统规范能够从ADL导出。
它应该能够代表大多数常见的架构风格。
它应该支持分析功能或提供快速生成原型实现。
面向对象范式
面向对象(OO)范式的形成源于一种新的编程方法的最初概念,而对设计和分析方法的兴趣则要晚得多。OO分析和设计范式是OO编程语言广泛采用的逻辑结果。
第一种面向对象的语言是Simula(真实系统的模拟),由挪威计算中心的研究人员于 1960 年开发。
1970 年,Alan Kay和他在 Xerox PARC 的研究小组创建了一台名为Dynabook的个人计算机,以及第一个用于对 Dynabook 进行编程的纯面向对象编程语言 (OOPL) - Smalltalk。
20世纪80年代,Grady Booch发表了一篇题为“面向对象设计”的论文,主要介绍了编程语言Ada的设计。在随后的版本中,他将自己的想法扩展到完整的面向对象的设计方法。
20 世纪 90 年代,Coad将Behave思想融入到面向对象的方法中。
其他重要的创新是James Rum Baugh的对象建模技术 (OMT) 和Ivar Jacobson的面向对象软件工程 (OOSE) 。
OO范式简介
OO 范式是任何软件开发的重要方法。大多数架构风格或模式(例如管道和过滤器、数据存储库和基于组件)都可以使用此范例来实现。
面向对象系统的基本概念和术语 -
目的
对象是面向对象环境中的现实世界元素,可能具有物理或概念存在。每个对象都有 -
将其与系统中其他对象区分开来的标识。
确定对象的特征属性以及对象所拥有的属性值的状态。
表示对象在其状态变化方面执行的外部可见活动的Behave。
可以根据应用程序的需要对对象进行建模。一个物体可能有物理存在,如顾客、汽车等;或无形的概念存在,如项目、流程等。
班级
类表示具有相同特征属性并表现出共同Behave的对象的集合。它给出了蓝图或可以从中创建的对象的描述。创建对象作为类的成员称为实例化。因此,对象是类的实例。
一个类的组成部分是 -
要从类实例化的对象的一组属性。一般来说,一个类的不同对象的属性值有一定的差异。属性通常称为类数据。
描述类对象Behave的一组操作。操作也称为函数或方法。
例子
让我们考虑一个简单的类 Circle,它表示二维空间中的几何图形圆。该类的属性可以识别如下 -
- x-坐标,表示中心的 x-坐标
- y 坐标,表示中心的 y 坐标
- a, 表示圆的半径
它的一些操作可以定义如下 -
- findArea(),计算面积的方法
- findCircumference(),一种计算周长的方法
- scale(),增加或减少半径的方法
封装
封装是将属性和方法在类中绑定在一起的过程。通过封装,类的内部细节可以对外部隐藏。它允许只能通过类提供的接口从外部访问类的元素。
多态性
多态性最初是一个希腊词,意思是采取多种形式的能力。在面向对象的范例中,多态性意味着以不同的方式使用操作,具体取决于它们所操作的实例。多态性允许具有不同内部结构的对象具有共同的外部接口。多态性在实现继承时特别有效。
例子
让我们考虑两个类,Circle 和 Square,每个类都有一个方法 findArea()。尽管类中方法的名称和用途相同,但每个类的内部实现(即计算面积的过程)不同。当 Circle 类的对象调用其 findArea() 方法时,该操作会查找圆的面积,而不会与 Square 类的 findArea() 方法发生任何冲突。
人际关系
为了描述一个系统,必须提供系统的动态(Behave)和静态(逻辑)规范。动态规范描述了对象之间的关系,例如消息传递。静态规范描述了类之间的关系,例如聚合、关联和继承。
消息传递
任何应用程序都需要许多对象以和谐的方式交互。系统中的对象可以通过使用消息传递来相互通信。假设系统有两个对象 - obj1 和 obj2。如果 obj1 希望 obj2 执行其方法之一,则对象 obj1 会向对象 obj2 发送一条消息。
组合或聚合
聚合或组合是类之间的一种关系,通过这种关系,一个类可以由其他类的对象的任意组合组成。它允许将对象直接放置在其他类的主体中。聚合被称为“部分”或“具有一个”关系,能够从整体导航到其部分。聚合对象是由一个或多个其他对象组成的对象。
协会
关联是一组具有共同结构和共同Behave的链接。关联描述了一个或多个类的对象之间的关系。链接可以定义为关联的实例。关联度表示连接中涉及的类的数量。次数可以是一元、二元或三元。
- 一元关系连接同一类的对象。
- 二元关系连接两个类的对象。
- 三元关系连接三个或更多类的对象。
遗产
它是一种机制,允许通过扩展和完善其功能来从现有类中创建新类。现有的类称为基类/父类/超类,新的类称为派生类/子类/子类。
如果超类允许,子类可以继承或派生超类的属性和方法。此外,子类可以添加自己的属性和方法,并且可以修改任何超类方法。继承定义了“is – a”关系。
例子
从一类哺乳动物中,可以派生出许多类,例如人类、猫、狗、牛等。人类、猫、狗和牛都具有哺乳动物的独特特征。此外,每一种都有其独特的特点。可以说,牛“是——一种”哺乳动物。
面向对象分析
在软件开发的面向对象分析阶段,确定系统需求,识别类,并确认类之间的关系。OO分析的目的是了解系统的应用领域和具体需求。此阶段的结果是需求规格说明以及对系统逻辑结构和可行性的初步分析。
面向对象分析中相互结合使用的三种分析技术是对象建模、动态建模和功能建模。
对象建模
对象建模根据对象开发软件系统的静态结构。它标识对象、对象可以分组到的类以及对象之间的关系。它还标识了每个类的主要属性和操作。
对象建模的过程可以通过以下步骤可视化 -
- 识别对象并分组
- 识别类之间的关系
- 创建用户对象模型图
- 定义用户对象属性
- 定义应对类执行的操作
动态建模
分析系统的静态Behave后,需要检查其相对于时间和外部变化的Behave。这就是动态建模的目的。
动态建模可以定义为“一种描述单个对象如何响应事件的方法,无论是由其他对象触发的内部事件,还是由外部世界触发的外部事件。”
动态建模的过程可以通过以下步骤可视化 -
- 识别每个对象的状态
- 识别事件并分析行动的适用性
- 构建动态模型图,包括状态转换图
- 用对象属性来表达每个状态
- 验证绘制的状态转换图
功能建模
功能建模是面向对象分析的最后一个组成部分。功能模型显示了对象内执行的过程以及数据在方法之间移动时如何变化。它规定了对象建模操作的含义和动态建模的动作。该功能模型对应于传统结构化分析的数据流图。
功能建模的过程可以通过以下步骤可视化 -
- 识别所有输入和输出
- 构建显示功能依赖关系的数据流程图
- 说明每个功能的目的
- 确定限制因素
- 指定优化标准
面向对象的设计
分析阶段之后,概念模型进一步发展为使用面向对象设计(OOD)的面向对象模型。在 OOD 中,分析模型中独立于技术的概念被映射到实现类,识别约束并设计接口,从而产生解决方案域的模型。OO设计的主要目的是开发系统的结构体系结构。
面向对象设计的阶段可以确定为 -
- 定义系统的上下文
- 设计系统架构
- 系统中对象的识别
- 设计模型的构建
- 对象接口规范
OO设计可以分为两个阶段——概念设计和详细设计。
概念设计
在此阶段,将确定构建系统所需的所有类。此外,每个班级都被分配了具体的职责。类图用于阐明类之间的关系,交互图用于显示事件的流程。也称为高层设计。
详细设计
在此阶段,根据交互图将属性和操作分配给每个类。开发状态机图来描述设计的进一步细节。它也称为低级设计。
设计原则
以下是主要设计原则 -
解耦原理
维护具有一组高度相互依赖的类的系统很困难,因为一个类的修改可能会导致其他类的级联更新。在面向对象设计中,可以通过引入新类或继承来消除紧密耦合。
确保凝聚力
内聚类执行一组密切相关的功能。缺乏内聚意味着——一个类执行不相关的功能,尽管它不影响整个系统的运行。它使得软件的整个结构难以管理、扩展、维护和更改。
开闭原则
根据这个原则,系统应该能够扩展以满足新的需求。系统现有的实现和代码不应因系统扩展而修改。此外,必须遵循开闭原则以下准则 -
对于每个具体类,必须维护单独的接口和实现。
在多线程环境中,将属性保持私有。
尽量减少全局变量和类变量的使用。
数据流架构
在数据流架构中,整个软件系统被视为对连续块或一组输入数据的一系列转换,其中数据和操作彼此独立。在这种方法中,数据进入系统,然后一次一个地流经模块,直到它们被分配到某个最终目的地(输出或数据存储)。
组件或模块之间的连接可以被实现为I/O流、I/O缓冲器、管道或其他类型的连接。数据可以以有环的图拓扑、无环的线性结构或树型结构的形式流动。
这种方法的主要目标是实现重用和可修改性的品质。它适用于涉及一系列明确定义的独立数据转换或对有序定义的输入和输出进行计算的应用程序,例如编译器和业务数据处理应用程序。模块之间有三种类型的执行顺序 -
- 批次顺序
- 管道和过滤器或非顺序管道模式
- 过程控制
批量顺序
批顺序是一种经典的数据处理模型,其中数据转换子系统只有在其前一个子系统完全通过后才能启动其过程 -
数据流将一批数据作为一个整体从一个子系统传送到另一个子系统。
模块之间的通信通过临时中间文件进行,这些文件可以被后续子系统删除。
适用于数据批量化、各子系统读取相关输入文件并写入输出文件的应用。
该架构的典型应用包括业务数据处理,例如银行业务和公用事业计费。
优点
提供更简单的子系统划分。
每个子系统可以是处理输入数据并产生输出数据的独立程序。
缺点
提供高延迟和低吞吐量。
不提供并发和交互接口。
实施需要外部控制。
管道和过滤器架构
这种方法强调通过连续组件对数据进行增量转换。在这种方法中,数据流由数据驱动,整个系统被分解为数据源、过滤器、管道和数据接收器等组件。
模块之间的连接是数据流,它是先进/先出缓冲区,可以是字节流、字符流或任何其他类型的此类流。该架构的主要特点是并发和增量执行。
筛选
过滤器是一个独立的数据流转换器或流转换器。它转换输入数据流的数据,对其进行处理,并将转换后的数据流写入管道以供下一个过滤器处理。它以增量模式工作,一旦数据通过连接的管道到达,它就开始工作。滤波器有两种类型:有源滤波器和无源滤波器。
有源滤波器
主动过滤器允许连接的管道拉入数据并推出转换后的数据。它与被动管道一起运行,被动管道提供用于拉和推的读/写机制。该模式用于UNIX管道和过滤机制。
无源滤波器
无源过滤器允许连接的管道将数据推入和拉出。它与活动管道一起运行,从过滤器中提取数据并将数据推送到下一个过滤器中。它必须提供读/写机制。
优点
为过多的数据处理提供并发和高吞吐量。
提供可重用性并简化系统维护。
提供过滤器之间的可修改性和低耦合性。
通过在通过管道连接的任何两个过滤器之间提供清晰的划分,提供简单性。
通过支持顺序和并行执行来提供灵活性。
缺点
不适合动态交互。
以 ASCII 格式传输数据需要较低的公分母。
过滤器之间的数据转换开销。
不提供过滤器协作交互来解决问题的方法。
动态配置此架构很困难。
管道
管道是无状态的,它们携带存在于两个过滤器之间的二进制或字符流。它可以将数据流从一个过滤器移动到另一个过滤器。管道使用少量上下文信息并且在实例化之间不保留状态信息。
过程控制架构
它是一种数据流架构,其中数据既不是批处理的顺序流,也不是管道流。数据流来自一组变量,这些变量控制流程的执行。它将整个系统分解为子系统或模块并将它们连接起来。
子系统的类型
过程控制架构将具有用于改变过程控制变量的处理单元和用于计算变化量的控制器单元。
控制器单元必须具有以下元素 -
受控变量- 受控变量为底层系统提供值,应由传感器测量。例如,巡航控制系统中的速度。
输入变量- 测量过程的输入。例如温控系统回风温度
操纵变量- 操纵变量值由控制器调整或更改。
流程定义- 它包括操纵某些流程变量的机制。
传感器- 获取与控制相关的过程变量值,并可用作重新计算操纵变量的反馈参考。
设定点- 它是受控变量的期望值。
控制算法- 用于决定如何操纵过程变量。
应用领域
过程控制架构适用于以下领域 -
嵌入式系统软件设计,系统由过程控制变量数据操纵。
应用程序,其目的是将过程输出的指定属性保持在给定的参考值。
适用于汽车巡航控制和楼宇温度控制系统。
控制汽车防抱死制动、核电站等的实时系统软件。
以数据为中心的架构
在以数据为中心的架构中,数据是集中的,并且被其他组件频繁访问,从而修改数据。这种风格的主要目的是实现数据的完整性。以数据为中心的体系结构由通过共享数据存储库进行通信的不同组件组成。这些组件访问共享数据结构并且相对独立,因为它们仅通过数据存储进行交互。
以数据为中心的架构最著名的例子是数据库架构,其中通用数据库模式是使用数据定义协议创建的——例如,RDBMS 中一组具有字段和数据类型的相关表。
以数据为中心的体系结构的另一个示例是 Web 体系结构,它具有通用数据模式(即 Web 的元结构)并遵循超媒体数据模型,并且进程通过使用共享的基于 Web 的数据服务进行通信。
组件类型
有两种类型的组件 -
中央数据结构或数据存储或数据存储库,负责提供永久数据存储。它代表当前状态。
数据访问器或独立组件的集合,在中央数据存储上运行、执行计算并可能返回结果。
数据访问者之间的交互或通信仅通过数据存储进行。数据是客户之间唯一的沟通方式。控制流将架构分为两类 -
- 存储库架构风格
- 黑板架构风格
存储库架构风格
在存储库架构风格中,数据存储是被动的,数据存储的客户端(软件组件或代理)是主动的,它们控制逻辑流。参与的组件检查数据存储中的更改。
客户端向系统发送请求以执行操作(例如插入数据)。
计算过程是独立的,并由传入请求触发。
如果事务输入流中的事务类型触发要执行的流程的选择,则它是传统数据库或存储库体系结构,或被动存储库。
这种方法广泛应用于 DBMS、图书馆信息系统、CORBA 中的接口存储库、编译器和 CASE(计算机辅助软件工程)环境。
优点
提供数据完整性、备份和恢复功能。
提供代理的可扩展性和可重用性,因为它们彼此之间没有直接通信。
减少软件组件之间瞬态数据的开销。
缺点
它更容易出现故障,并且可能发生数据复制或重复。
数据存储的数据结构及其代理之间的高度依赖性。
数据结构的变化对客户端影响很大。
数据的演变是困难且昂贵的。
在网络上移动分布式数据的数据的成本。
黑板架构风格
在 Blackboard 架构风格中,数据存储是主动的,其客户端是被动的。因此,逻辑流由数据存储中的当前数据状态决定。它有一个黑板组件,充当中央数据存储库,并且内部表示由不同的计算元素构建和作用。
黑板中存储了许多独立作用于公共数据结构的组件。
在这种风格中,组件仅通过黑板进行交互。每当数据存储发生更改时,数据存储都会向客户端发出警报。
解决方案的当前状态存储在黑板中,并由黑板的状态触发处理。
当数据发生变化时,系统向客户端发送称为触发器和数据的通知。
这种方法存在于某些人工智能应用和复杂应用中,例如语音识别、图像识别、安全系统和业务资源管理系统等。
如果中央数据结构的当前状态是选择要执行的进程的主要触发因素,则存储库可以是黑板,并且该共享数据源是活动代理。
与传统数据库系统的主要区别在于,黑板架构中计算元素的调用是由黑板的当前状态触发的,而不是由外部输入触发。