概括:
本文从程序的运行时结构和源代码的组织结构两个方面讨论了系统架构设计中应考虑的各种因素,并列出了系统架构设计文档中应考虑的一些问题。
1. 与架构相关的几个基本概念
1、模块():完成指定功能的一组语句,包括:输入、输出、逻辑处理功能、内部信息、运行环境(与功能相对应,但不是一一对应的关系)。
2. 组件():系统中非常重要的、几乎独立的、可替换的部分,它在明确定义的架构环境中实现精确的功能。
3、模式():指一种经过验证适合至少一种实际环境(更多时候是几种环境)的解决方案模板(用于结构和行为)。在UML中:模式是通过参数化协作来表示的,但是UML并不直接对模式的其他方面进行建模(例如使用结果列表、使用示例等,这些可以用文本来表示)。存在各种范围和抽象级别的模式,例如架构模式、分析模式和设计模式。还有代码模式或实现模式。模式将帮助我们抓住要点。建筑也有模式。例如,对于系统结构设计,我们使用代理模式(通过使用代理而不是实际代理)。对象,使程序能够控制对该对象的访问);对于交互系统,我们针对具体问题使用MVC(M模型(对象)/V视图(输出管理)/C控制器(输入处理))模式。因此,我们也可以根据需求的特点,采用相应的模式来设计架构。
4、架构模式( ):代表软件系统的基本结构组织方案。它提供了一组预定义的子系统,指定了它们的职责,并包括用于组织它们之间关系的规则和指南。
5. ():在模型中将包分组到同一抽象级别的特定方法。通过分层,子系统在逻辑上被划分为许多集合,层间关系的形成必须遵循一定的规则。通过分层,可以限制子系统之间的依赖关系,使系统更加松散耦合,从而更容易维护。 (层是架构的水平划分,分区是架构的垂直划分)。
6、系统分层的几种常用方法:
1)常用的三层服务:用户层、业务逻辑层、数据层;
2)多层结构技术组成模型:表示层、中间层、数据层;
3)网络系统一般采用三层结构:核心层、汇聚层、接入层;
4)RUP典型分层方式:应用层、专业业务层、中间件层、系统软件层;
5)基于Java的B/S模式系统结构:浏览器端、服务器端、请求接收层、请求处理层;
6)一定的六层结构:功能层(用户界面)、模块层、装配层(软件总线)、服务层(数据处理)、数据层、核心层;
7) 架构(设计和建造建筑物的艺术和科学):RUP 中的定义:软件系统的架构(在给定点)是指系统重要组件的组织或结构。这些重要的组件通过接口与越来越小的组件以及由接口组成的组件进行交互; 《软件架构实践》中的定义:某种软件或计算系统的软件架构是组成系统的一个或多个结构,它们构成了软件。每个部分形成了这些组件的外部可见属性和相互联系; IEEE 1471-2000中的定义:架构是系统在其环境中的最高级别概念。软件系统的架构是通过接口交互的重要组件(在特定时间点)的组织或结构,而这些组件又由更小的组件和接口组成。 (“建筑”可以用作名词,也可以用作动词。“建筑”作为动词相当于“建筑设计”)
8)架构描述方法:“4+1”视图(用例视图、设计视图、实现视图、流程视图、配置视图)是架构描述广泛使用的模型; RUP流程的架构描述模板是在“4+1”视图的基础上可选的数据视图(从永久数据存储的角度来描述系统);惠普的软件描述模板也是基于“4+1”的观点。
9)结构:软件架构是多种结构的体现。结构是从不同角度观察系统架构而产生的视图。就像建筑物的结构可以根据观察的动机和起点具有多种含义一样,软件架构也以多种结构表现出来。常见的软件结构包括:模块结构、逻辑或概念结构、过程或协调结构、物理结构、使用结构、调用结构、数据流、控制流、类结构等。
2、架构设计应考虑的因素概述
模块架构设计可以从程序的运行时结构和源代码的组织结构来考虑。
1、程序运行时结构中的考虑:
1) 要求的符合性:正确性、完整性;功能需求、非功能需求;
2)总体性能(内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法、对与网络、硬件和其他系统的接口性能的影响);
3)运行可管理性:易于控制系统运行、监控系统状态、错误处理;模块之间的通信简单;与可维护性不同;
4)与其他系统的接口兼容性;
5) 网络和硬件接口的兼容性和性能;
6)系统安全;
7)系统可靠性;
8)业务流程的可调整性;
9)业务信息的可调整性
10) 易于使用
11)架构风格的一致性
注:运行时负载均衡可以从系统性能和系统可靠性方面考虑。
2.关于源代码组织结构的考虑:
1)开发可管理性:便于人员分工(模块独立、开发工作负载均衡、进度优化、防止人员流动对开发的影响)、配置管理、规模合理、复杂度适中;
2)可维护性:不同于操作可管理性;
3)可扩展性:系统解决方案的升级、扩展、扩展性能;
4)可移植性:不同的客户端、应用服务器、数据库管理系统;
5)符合要求(考虑源代码的组织结构)。
3. 程序运行时结构中的考虑
1. 要求的符合性:正确性、完整性;功能需求、非功能需求
软件项目的主要目标是满足客户需求。在设计架构的时候,大家更多地考虑的是使用哪种操作平台、编程语言、开发环境、数据库管理系统等问题。与客户需求相关的问题没有得到充分、系统的考虑。如果无论架构有多好,都无法满足客户指定的某个功能或非功能需求,则应与客户协调,将该需求从项目范围和需求规格说明书中删除。否则,架构设计应该以满足所有客户的显性需求为最基本的目标,并尽力满足其隐性需求。 (客户的非功能性需求可能包括接口、系统安全性、可靠性、可移植性、可扩展性等,这些在其他章节中有详细介绍)
一般来说,功能需求决定业务架构,非功能需求决定技术架构,变更案例决定架构范围。需求知识告诉我们,功能需求定义了软件可以做什么。我们需要根据业务需求来设计业务架构,以便未来的软件能够满足客户的需求。非功能性需求定义了一些关于性能和效率的约束和规则。我们的技术架构必须能够满足这些约束和规则。变更案例是对未来可能发生的变更的估计。结合功能需求和非功能需求,我们可以确定需求的范围,进而确定架构的范围。 (本段来自林星)
这里举一个前几年由于某些客户需求错误导致的架构设计问题导致的系统性能和可靠性问题的小例子: 这个系统本身的需求比较简单,就是结合某个业务的整个历史记录在某个城市。文件卡经过扫描和存储,以便可以按名称搜索。需求阶段,客户称卡片数量约为20万张,但出于对客户的信任,需求研究员并未核实数据总量。由于数据量较小,且未来数据不会增加,在计算了20万卡的总体容量后,决定采用可单机使用的中小型数据库管理系统或连接到互联网。当系统完成并录入数据时,发现至少有60万条数据。使用这样的中小型数据库管理系统不仅会导致系统性能问题,而且其可靠性也非常脆弱,必须重新设计系统。从这个小教训可以看出,在需求阶段,不仅要把客户的功能需求调查清楚,还要把一些隐含非功能需求的数据调查清楚,作为架构设计的依据。
功能需求的正确性在架构设计文档中可能不容易验证(需要人工)。为了功能需求的完整性,需要使用所需功能与对应模块的对照表进行跟踪和追溯。对于非功能需求的正确性和完整性,可以通过非功能需求与相应设计策略的对照表来进行追溯评估。
“软件设计工作只有立足于用户需求,基于可行的技术,才能成功。”
2、整体表现
性能其实也是客户需求的一部分。当然,它可能是明确的,但很多可能是隐含的。我这里单独列出来,解释一次。性能是设计解决方案的重要标准。性能考虑的不是单个客户端的性能,而是系统整体的综合性能;
性能设计应考虑以下几个方面:内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法以及与网络、硬件和其他系统的接口对性能的影响;
几点建议:算法优化和负载均衡是性能优化的方向。经常调用的模块要特别注意优化。占用大量内存的变量在不使用时应及时清理。当需要下载的网页主题文件过大时,应将其分解为几个部分,以便用户首先显示主要部分。
3. 运营管理性
系统架构设计应该使系统能够预测系统故障并将其消灭在萌芽状态。当今的系统正逐渐变得更加复杂和大规模。仅靠一个或几个人的管理已经不够了。而且,人类的反应显然不足以应对某些突发事件。因此,通过合理的系统架构来规划系统运行资源,有利于系统运行的控制、系统状态的监控以及有效的错误处理;为了实现上述目标,模块之间的通信应尽可能简单,并建立合理、详细的系统操作日志。自动审计运行日志,了解系统运行状态并进行有效的错误处理; (运营可管理性与可维护性不同)
4、与其他系统的接口兼容性(略)
网络和硬件接口的兼容性和性能(略)
5、系统安全
随着计算机应用的不断深入和扩展,涉及的部门和信息越来越多,大量的机密信息在网络上传输。因此,系统安全性的考虑就成为系统设计的关键,需要从各个方面、各个方面进行考虑,以保证数据的绝对安全。
6、系统可靠性
系统可靠性是现代信息系统的一个重要特征。由于人们的日常工作越来越依赖于系统,因此系统必须可靠。系统架构设计可以考虑系统冗余,尽可能避免单点故障。系统可靠性是指系统在给定的时间间隔和给定的环境条件下,按照设计要求成功运行程序的概率。成功的运行不仅保证系统能够正确运行、满足功能要求,还要求当系统出现意外故障时,能够尽快恢复正常运行而不损坏数据。
7、业务流程的可调整性
应考虑客户业务流程可能发生的变化,因此在设计系统架构时,尽量消除业务流程的约束,即将流程中的每个业务节点视为一个独立的对象,设计成独立的模块或组件,并充分考虑其与其他各种业务对象模块或组件的接口,通过业务对象模块之间的相互调用来实现各种业务。这样,当业务流程发生有限的变化时(各业务模块本身的业务逻辑不变),更容易修改系统程序模块或组件之间的调用关系来实现新的需求。如果将这种调用关系设计为存储在配置库的数据字典中,那么甚至不需要修改程序代码,只需要修改数据字典中的模块或组件调用规则即可。
8、业务信息的可调整性
需要考虑客户业务信息可能发生的变化,因此在设计系统架构时必须尽量减少业务信息的调整对代码模块的影响范围。
9. 易于使用
易用性是一个无需提及的必然要求,而易用性与系统架构密切相关。 (1.0)的失败和后续改进版本的成功就说明了这个问题。 (1.0) 窗口和菜单层次过多,用户更喜欢界面简单、操作快捷。出现故障应及时纠正,但最好不要等到出现故障才纠正。这会浪费巨大的财力和物力,所以最好在系统建设阶段就考虑到所有需要考虑的因素。当然,易用性必须与系统安全性协调平衡,易用性也必须与业务流程的可调整性、业务信息的可调整性协调平衡。 “满足用户的需求,让用户方便使用,同时让操作过程尽可能简单,这是设计的基础。”
10、架构风格的一致性
软件系统的架构风格与建筑风格有些相似(如中式、哥特式、希腊复古式)。软件架构风格可分为数据流架构风格、调用返回架构风格、独立组件架构风格、以数据为中心的架构风格和虚拟机架构风格。每个风格又可以分为几个子风格。架构风格的一致性并不要求一个软件系统只能采用一种风格。就像架构风格可以是中西结合一样,软件系统也可以有异构的架构风格(分为局部异构、层次异构、并行异构)。质),即多种风格的综合,但这样的综合要考虑某些方面的一致性和协调性。每种风格都有其使用时间,应根据系统中最强调的质量属性来选择。
4. 源代码组织结构注意事项
1. 开发可管理性
便于分工(模块独立、开发工作负载均衡、优化进度、防止人员流动对开发的影响:良好的架构还应该有助于减轻项目团队的压力和紧张,提高项目效率)软件开发),便于配置管理,规模合理,复杂度适当;
1)方便人员分工——模块独立性和层次性
模块独立性和层次性是为了保证项目开发成员工作的相对独立性。模块连接方式应该是垂直的而不是水平的,模块之间应该是树形结构而不是网状结构或交叉结构,以便最大限度地减少开发人员之间的沟通和模块开发约束。同时,模块独立性也更有利于配置管理工作。如今,越来越多的软件开发是在偏远地区进行的。开发团队的成员可能位于不同的城市,甚至不同的国家。因此,一种方便远程开发人员分工和配置管理的源代码组织结构是非常有必要的。
2)有利于开发工作的分工-负载平衡
不仅开发出来的软件系统需要负载均衡,开发过程中开发团队成员之间工作任务的负载均衡也很重要。所谓工作任务负载均衡,就是通过合理的任务划分,根据开发人员的特点来分配任务,尽量让项目组中的每个人每次都有用。这就要求在设计架构时要充分考虑项目组现有的人力资源,在满足客户需求的基础上实现开发工作的负载均衡,以提高整体开发效率。
3)便于人员分工——优化排班;
调度优化的前提是模块独立性和对模块开发顺序约束的理解。利用工作分解结构对所有程序编码工作进行分解,获取每项工作的输入、输出、所需资源、持续时间、前期应完成的工作以及完成后可以进行的工作。然后估算每个模块所需的时间,分析每个模块的并行性和串行性(顺序约束),绘制网络图,找出影响整体进度的关键模块,计算关键路径,最后将网络图调整为确保日程安排。优化。
有一个著名的谜题,叫做烧烤攻略:约翰逊在他家外面有一个烧烤炉,可以同时烤两块肉。每块肉的每一面都需要烤10分钟。现在他要烤三块肉给那些又饿又不耐烦的人。一家三口。问题是如何在最短的时间内烤三块肉。一般的方法是20分钟烤前两片,20分钟再烤第三片。有一个更好的方法可以节省10分钟,想一想。
4)便于分工——防止员工流动对发展的影响
员工流失在软件行业是司空见惯的事,也成为了普遍的风险。作为针对这一风险的有效防范措施之一,在架构设计中可以考虑并防范员工流动对发展的影响。主要思想仍然是模块的独立性(追求高内聚、低耦合),组件化是目前流行的趋势。
5)有利于配置管理(独立性、层次性)
配置管理的效益与人员分工的效益之间存在一定的联系。除了逻辑上的模块组件有利于人员分工外,各个模块的物理源代码层次结构、目录结构以及源代码文件的部署也应该有利于人员分工和配置管理。 (虽然现在配置管理工具的功能更加强大,但是清晰的源代码分割和模块分割是非常有益的)。
6)合理的规模和适当的复杂性
合理的大小和适中的复杂度可以平衡开发工作的负载,方便日程安排,也可以减少系统运行时不必要的内存资源浪费。对于代码可读性和系统可维护性也有一定的好处。另外,模块太大往往会导致系统分解不充分,而模块太小则可能会降低模块的独立性,使系统接口变得复杂。
2、可维护性
方便在系统出现故障时及时方便地查找故障原因及源代码位置,并方便进行部分修改和裁剪; (可维护性不同于操作可管理性)
3、可扩展性:系统解决方案的升级、扩展和性能扩展
系统建成后,将有较长的运行周期。在这个周期中,应用不断增加,应用水平不断升级。因此,所采用的架构设计等方案充分考虑了升级、扩容、扩容的可行性和便利性。
4. 便携性
不同的客户端、应用服务器、数据库管理系统:如果潜在客户使用的客户端可能使用不同的操作系统或浏览器,其可移植性必须考虑客户端程序的可移植性,或者尽量不要将业务逻辑放在客户端;数据处理的业务逻辑放在数据库管理系统中会有更好的性能,但如果不确定客户群使用的是同一个数据库管理系统,则业务逻辑不能放在数据库管理系统中;
要实现可移植性,必须注重标准化和开放性:只有广泛采用和遵循国际标准,开发开放性强的产品,才能保证各类系统的充分互联,从而使产品更具市场竞争力,也才能保证产品的可移植性。为以后的系统迁移和升级提供基础。
5. 符合要求
从源代码的组织结构来看,对需求的符合主要考虑软件代码和架构的最小冗余,以应对用户需求可能发生的变化(同时使系统具有一定的可扩展性)。
5、编写系统架构设计文档时应考虑的问题
当需求开发完成大约 80% 时,就应该开始架构工作。不必等到需求开发完成。项目经理需要用具体的判断来评估此时是否足以开始构建软件架构。
给出一致的轮廓:系统概述。系统架构需要现有的一般描述,以便开发人员可以从数千个细节甚至数十个模块或对象类中构建一致的轮廓。
架构的目标应该是清楚地解释系统概念。架构应该尽可能简单。最好的架构文档应该简单、简短、清晰、不杂乱,解决方案也应该自然。
体系结构首先应定义主要的上层子系统,描述每个子系统的任务,并提供每个子系统中的模块或对象类的初步列表。
架构应该描述不同子系统之间的通信方式,一个好的架构应该尽量减少子系统之间的通信关系。
成功架构的一个重要特征是识别最有可能改变的领域。您应该列出程序中最有可能更改的部分,并描述架构的其他部分将如何适应。
复用分析和外包:缩短软件开发周期、降低成本的有效解决方案不一定是自己开发软件。现有软件可以重复使用或外包。应考虑对架构的影响。
除了系统组织的问题外,架构还应该关注对细节有全面影响的设计决策,深入到这些决策领域:外部软件接口(兼容性、通信方式、传输数据结构)、用户界面(用户界面)和系统层次结构)、数据库组织和内容、非数据库信息、关键算法、内存管理(配置策略)、并行性、安全性、可移植性、网络多人操作、错误处理。
需要保证需求的可追溯性,即保证每个需要的功能都有对应的模块来实现。
架构的设计不能仅仅基于静态的系统目标,还应该考虑动态的开发过程,如人力资源、进度要求、开发环境的满意度等。该架构必须支持分阶段规划,并且应该能够提供如何开发和完成分阶段规划的方法。您不应依赖无法独立运行的子系统架构。找出系统各部分的依赖关系和依赖关系,形成开发计划。
六、结论
系统架构设计与具体的开发平台千差万别密切相关,因此这里不能给出通用的解决方案,主要是为了说明需要考虑哪些因素。对于每一个因素以及本文未提及的因素的设计策略,都需要软件架构设计者在具体的开发实践中灵活掌握。不同的因素有时是矛盾的,架构设计需要根据具体情况进行平衡。