𝓝𝓮𝓶𝓸&博客

【软件工程】常用总结

  • 软件工程的框架可概括为:目标过程原则

软件完整流程

image

上面这张动图描述了将代码部署到公司生产环境的详细步骤。
1.产品负责人根据需求编写用户故事开启此流程。
2.开发团队从任务清单中选出这些用户故事,开始为期两周的迭代开发。
3.开发人员将代码提交至 Git 仓库。
4.代码提交后,Jenkins 会自动触发构建。此时,代码需要满足单元测试标准、达到设定的覆盖率,并通过 SonarQube 中的检测标准。
5.构建成功后,其结果将存放在 artifactory 中,接着会部署到开发环境进行验证。
6.可能有不同的团队处理各种功能模块。为确保独立测试,这些功能会部署至 QA1 和 QA2。
7.QA 团队对新部署的环境进行系列测试,包括 QA 测试、回归测试和性能测试。
8.当 QA 验证无误后,部署至 UAT 环境,此时不仅 QA,开发团队和产品负责人也会进行用户验收测试。
9.如果 UAT 通过,这些版本将按预定计划上线至生产环境。为稳妥起见,我们可能分阶段、分批上线,利用如功能切换、金丝雀发布等策略来降低风险。
10.SRE 负责实时监测线上环境,他们采用众多如 ELK Stack、Prometheus 和 Skywalking 等的工具来分析日志和追踪流程。如果发现异常,他们会迅速通知 QA 和开发团队,按照既定的优先级来修复这些问题。

开发模型

UML在其中的各个阶段都有不同的应用,如下所述。
(1)需求阶段:采用用例图描述需求。
(2)分析阶段:采用类图描述静态结构,采用顺序图、协作图、活动图和状态图描述动态行为。
(3)设计阶段:采用类图对类的接口进行设计。
(4)开发阶段:采用某种面向对象语言实现。
(5)测试阶段:单元测试采用类图和类的规格说明书;集成测试采用类图、协作图;系统测试采用用例图。
(6)交付阶段:采用构件图和部署图。

瀑布模型

瀑布模型产生的历史背景是20世界70年代出现的软件危机,该模型将软件开发分为若干阶段,由于其类似于瀑布从上到下的过程,故称其为“瀑布模型”。

  • 特点:
    • 阶段间具有顺序性和依赖性:
      • 前一阶段完成后,才能开始后一阶段
      • 前一阶段的输出文本为后一阶段的输入文本
    • 推迟实现的观点
    • 质量保证:
      • 每个阶段必须交付出合格的文档
      • 对文档进行审核
  • 缺点:
    开始需要把需求做到最全,惧怕用户测试中的反馈,惧怕需求变更。

V模型

V模型是在瀑布模型的基础上发展而来的。

RAD(Rap Application Development,快速应用开发)模型是软件开发过程中的一个重要模型,由于其模型构图形似字母V,所以又称软件测试的 V模型。它通过开发和测试同时进行的方式来缩短开发周期,提高开发效率。

阶段步骤

V模型大体可以划分为以下几个不同的阶段步骤:需求分析、概要设计、详细设计、软件编码、单元测试、集成测试、系统测试、验收测试

  • 需求分析:
    首先要明确客户需要的是什么,需要软件作成什么样子,需要有哪几项功能,这一点上比较关键的是分析师和客户沟通时的理解能力与交互性。要求分析师能准确地把客户所需要达到的功能、实现方式等表述出来,给出分析结果,写出需求规格说明书。
  • 概要设计:
    主要是架构的实现,指搭建架构、表述各模块功能、模块接口连接和数据传递的实现等多项事务。
  • 详细设计:
    对概要设计中表述的各模块进行深入分析、对各模块组合进行分析等,这一阶段要求达到伪代码级别,已经把程序的具体实现的功能、现象等表述出来。其中需要包含数据库设计说明。
  • 软件编码:
    按照详细设计好的模块功能表,编程人员编写出实际的代码。
  • 单元测试:
    按照设定好的最小测试单元进行按单元测试,主要是测试程序代码,为的是确保各单元模块被正确的编译。
    单元的具体划分,依据不同的单位、不同的软件而有所不同,比如有具体到模块的测试,也有具体到类、函数的测试等。

    单元测试是在编码完成后首先要进行的测试工作,主要针对每个模块的程序,测试其模块接口、局部数据结构、边界条件、覆盖条件和出错处理。单元测试大多从程序内部结构出发设计测试用例,即多采用白盒测试方法。单元测试通常由编码人员自己来完成,因而也有人把编码和单元测试考虑成一个开发阶段。

  • 集成测试:
    经过了单元测试后,将各单元组合成完整的体系,主要测试各模块间组合后的功能实现情况,以及模块接口连接的成功与否,数据传递的正确性等。
    其主要目的是检查软件单位之间的接口是否正确
    根据集成测试计划,一边将模块或其他软件单位组合成系统,一边运行该系统,以分析所组成的系统是否正确,各组成部分是否合拍。

    在每个模块完成单元测试后,才能进行集成测试。集成测试需要按照设计时做出的结构图把各模块连接起来,以发现概要设计中模块之间接口设计的问题,其目的是检查模块是否已正确地合并成满足规格的产品。

  • 系统测试:
    经过了单元测试和集成测试以后,我们要把软件系统搭建起来,按照软件规格说明书中所要求,测试软件其性能、功能等是否和用户需求相符合,在系统中运行是否存在漏洞,等。

    集成测试完成后,分散开发的模块被连接起来,构成完整的程序,接下来就要进行系统测试。系统测试是将经过集成测试的软件,作为计算机系统的一个部分,与系统中其他部分结合起来,在实际运行环境下对计算机系统进行的一系列严格有效的测试,发现软件潜在的问题,保证系统的正常运行。系统测试包括功能测试,性能测试,压力测试,容量测试,安全性测试等等。

  • 验收测试:
    主要就是用户在拿到软件的时候,在使用现场,会根据前边所提到的需求,以及规格说明书来做相应测试,以确定软件达到符合效果的。

缺陷及解决思路

  • 缺陷:
    V模型仅仅把测试过程作为在需求分析、系统设计及编码之后的一个阶段,忽视了测试对需求分析,系统设计的验证,需求的满足情况一直到后期的验收测试才被验证。

  • 解决思路:
    当一个软件开发的时候,研发人员和测试人员需要同时工作,测试在软件做需求分析的同时就会有测试用例的跟踪,这样,可以尽快找出程序错误和需求偏离,从而更高效的提高程序质量,最大可能的减少成本,同时满足用户的实际软件需求。

适用范围

V模式是一种传统软件开发模型,一般适用于一些传统信息系统应用的开发;而一些高性能高风险的系统、互联网软件,或一个系统难以被具体模块化的时候,就比较难做成V模式所需的各种构件,需要更强调迭代的开发模型或者敏捷开发模型。

W模型

W模型:由Evolutif公司提出,相对于V模型,W模型增加了软件开发各阶段中同步进行的验证和确认活动。

如图所示,由两个V字型模型组成,分别代表测试与开发过程,图中明确表示出了测试开发的并行关系。

  • 优点:
    • 开发伴随着整个开发周期,需求和设计同样要测试;
        - 更早的介入测试,可以发现初期的缺陷,修复成本低;
    • 分阶段工作,方便项目整体管理。
  • 缺点:
    • 开发和测试依然是线性的关系,需求的变更和调整,依然不方便;
    • 如果没有文档,根本无法执行w模型;对于项目组成员的技术要求更高!

增量模型

增量模型:把软件分成许多个构件,每个构件分别当作一个软件来分析、设计、编码、测试。开发人员一次一个构件的提交给用户,最后组装到一起。

  • 优点:
    • 一开始不用投入太多人力,如果核心产品很受欢迎,则可增加人力实现下一个增量;
    • 可先发布部分功能给用户,让客户逐渐适应。
  • 缺点:
    并行开发构件有可能遇到不能集成的风险,软件必须具备开放式的体系结构。

螺旋模型

螺旋模型:在快速原型模型的每一个原型前引入一个非常严格的风险分析,每个模型经过制定计划、风险分析、实施工程、客户评估四步走。每个原型都标识一个或多个主要风险,直到所有的主要风险因素都被确定。螺旋模型由风险驱动,强调可选方案和约束条件从而支持软件的重用,有助于将软件质量作为特殊目标融入产品开发之中。

  • 优点:
    • 设计上的灵活性,可以在项目的各个阶段进行变更;
    • 以小的分段来构建大型系统,使成本计算变得简单容易;
    • 客户始终参与每个阶段的开发,保证了项目不偏离正确方向以及项目的可控性;
  • 缺点:
    • 采用螺旋模型需要具有相当丰富的风险评估经验和专门知识,在风险较大的项目开发中,如果未能够及时标识风险,势必造成重大损失;
    • 过多的迭代次数会增加开发成本,延迟提交时间。

喷泉模型

喷泉模型:以用户需求为动力,以对象为驱动的模型,主要用于描述面向对象的软件开发过程。该模型认为软件开发过程自下而上周期的各阶段是相互迭代和无间隙的特性。喷泉模型不像瀑布模型那样,需要分析活动结束后才开始设计活动,设计活动结束后才开始编码活动。该模型的各个阶段没有明显的界限,开发人员可以同步进行开发。

  • 优点:
    可以提高软件项目开发频率,节省开发时间,适应于面向对象的软件开发过程。
  • 缺点:
    由于喷泉模型在各个开发阶段是重叠的,因此在开发过程中需要大量的开发人员,因此不利于项目的管理。

喷泉模型

软件生命周期

瀑布型生命周期

瀑布型生命周期包括可行性分析与开发项计划、需求分析、设计(概要设计和详细设计)、编码、测试、维护等阶段。

阶段步骤

  • 问题的定义及规划:
    此阶段是软件开发方与需求方共同讨论,主要确定软件的开发目标及其可行性。
  • 需求分析:
    在确定软件开发可行的情况下,对软件需要实现的各个功能进行详细分析。需求分析阶段是一个很重要的阶段,这一阶段做得好,将为整个软件开发项目的成功打下良好的基础。"唯一不变的是变化本身。",同样需求也是在整个软件开发过程中不断变化和深入的,因此我们必须制定需求变更计划来应付这种变化,以保护整个项目的顺利进行。
  • 软件设计:
    此阶段主要根据需求分析的结果,对整个软件系统进行设计,如系统框架设计,数据库设计等等。软件设计一般分为总体设计和详细设计。好的软件设计将为软件程序编写打下良好的基础。
  • 程序编码:
    此阶段是将软件设计的结果转换成计算机可运行的程序代码。在程序编码中必须要制定统一,符合标准的编写规范。以保证程序的可读性,易维护性,提高程序的运行效率。
  • 软件测试:
    在软件设计完成后要经过严密的测试,以发现软件在整个设计过程中存在的问题并加以纠正。整个测试过程分单元测试、组装测试以及系统测试三个阶段进行。测试的方法主要有白盒测试和黑盒测试两种。在测试过程中需要建立详细的测试计划并严格按照测试计划进行测试,以减少测试的随意性。
  • 运行维护:
    软件维护是软件生命周期中持续时间最长的阶段。在软件开发完成并投入使用后,由于多方面的原因,软件不能继续适应用户的要求。要延续软件的使用寿命,就必须对软件进行维护。软件的维护包括纠错性维护和改进性维护两个方面。

高内聚低耦合

  • 内聚:是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系;

  • 耦合:是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。

  • 耦合性:也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。

  • 内聚性:又称块内联系。指模块的功能强度的度量,即一个模块内部各个元素彼此结合的紧密程度的度量。若一个模块内各元素(语名之间、程序段之间)联系的越紧密,则它的内聚性就越高。

  • 所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。

  • 对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。

耦合

耦合可以分为以下几种,它们之间的耦合度由高到低排列如下:

  • 内容耦合:一个模块直接访问另一模块的内容,则称这两个模块为内容耦合。
    内容耦合可能在汇编语言中出现。大多数高级语言都已设计成不允许出现内容耦合。
    这种耦合的耦合性最强,模块独立性最弱。
  • 公共耦合:一组模块都访问同一个全局数据结构,则称之为公共耦合。
    公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。
    如果模块只是向公共数据环境输入数据,或是只从公共数据环境取出数据,这属于比较松散的公共耦合;
    如果模块既向公共数据环境输入数据又从公共数据环境取出数据,这属于较紧密的公共耦合。
  • 外部耦合:一组模块都访问同一全局简单变量,而且不通过参数表传递该全局变量的信息,则称之为外部耦合。
  • 控制耦合:****模块之间传递的不是数据信息,而是控制信息例如标志、开关量等,一个模块控制了另一个模块的功能。
  • 标记耦合:****调用模块和被调用模块之间传递数据结构,而不是简单数据,同时也称作特征耦合。
    标记耦合的模块间传递的不是简单变量,而是像高级语言中的数据名、记录名和文件名等数据结果,这些名字即为标记,其实传递的是地址
  • 数据耦合:****调用模块和被调用模块之间只传递简单的数据项参数。相当于高级语言中的值传递
  • 非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。
    耦合度最弱,模块独立性最强

总结:耦合是影响软件复杂程度和设计质量的一个重要因素,为提高模块的独立性,应建立模块间尽可能松散的系统,在设计上我们应采用以下原则:若模块间必须存在耦合,应尽量使用数据耦合,少用控制耦合,慎用或有控制地使用公共耦合,并限制公共耦合的范围,尽量避免内容耦合。

内聚

内聚有如下的种类,它们之间的内聚度由弱到强排列如下:

  • 偶然内聚:一个模块内的各处理元素之间没有任何联系,只是偶然地被凑到一起
    这种模块也称为巧合内聚,内聚程度最低
  • 逻辑内聚:这种模块把几种相关的功能组合在一起,每次被调用时,由传送给模块参数来确定该模块应完成哪一种功能。
  • 时间内聚:需要同时执行的动作组合在一起,形成的模块称为时间内聚模块。
  • 过程内聚:构件或者操作的组合方式是,允许在调用前面的构件或操作之后,马上调用后面的构件或操作,即 使两者之间没有数据进行传递。
    简单的说就是如果一个模块内的处理元素是相关的,而且必须以特定次序执行,则称为过程内聚。
  • 通信内聚(信息内聚):指模块内所有处理元素都在同一个数据结构上操作或所有处理功能都通过公用数据而发生关联(有时称之为信息内聚)。
    即 指模块内各个组成部分都使用相同的数据数据或产生相同的数据结构
  • 顺序内聚:一个模块中各个处理元素和同一个功能密切相关,而且这些处理必须顺序执行,通常前一个处理元素的输出是后一个处理元素的输入。
    例如,某模块完成工业产值求值的功能,前一个功能元素求总产值,后一个功能元素求平均产值,显然该模块内两部分紧密关联。
    顺序内聚的内聚度比较高,但缺点是不如功能内聚易于维护。
  • 功能内聚:模块内所有元素的各个组成部分全部都为完成同一个功能而存在,共同完成一个单一的功能,模块已不可再分。即 模块仅包括为完成某个功能所必须的所有成分,这些成分紧密联系、缺一不可。
    功能内聚是最强的内聚,其优点是它的功能明确。判断一个模块是否功能内聚,一般从模块名称就能看出。
    如果模块名称只有一个动词和一个特定的目标(单数名词),一般来说就是功能内聚,如:“计算水费”、“计算产值”等模块。功能内聚一般出现在软件结构图的较低层次上。
    功能内聚模块的一个重要特点是:他是一个“暗盒”,对于该模块的调用者来说,只需要知道这个模块能做什么,而不需要知道这个模块是如何做的。

总结:在模块划分时,要遵循“一个模块,一个功能”的原则,尽可能使模块达到功能内聚。

高内聚,低耦合的系统有什么好处呢?
事实上,短期来看,并没有很明显的好处,甚至短期内会影响系统的开发进度,因为高内聚,低耦合的系统对开发设计人员提出了更高的要求。
高内聚,低耦合的好处体现在系统持续发展的过程中,高内聚,低耦合的系统具有更好的重用性,维护性,扩展性,可以更高效的完成系统的维护开发,持续的支持业务的发展,而不会成为业务发展的障碍。

posted @ 2020-01-12 17:34  Nemo&  阅读(503)  评论(0编辑  收藏  举报