软件工程(三) 软件开发环境、工具、重用、再工程、产品线

软件开发环境与工具

软件工具

软件工具按软件过程活动分为以下三类:

  1. 软件开发工具 :这类工具直接支撑软件开发全过程 ,用于辅助开发人员进行需求分析、设计、编码与排错等开发活动。具体包括需求分析工具、设计工具、编码与排错工具以及测试工具。所有这些工具贯穿软件生命周期的开发阶段,确保开发步骤高效执行。
  2. 软件维护工具 :主要用于软件交付后的维护阶段,辅助维护人员对软件代码及其文档进行维护活动 。包括版本管理工具 (如VSS、CVS、SCCS、SVN等)、文档分析工具开发信息库工具、逆向工程工具和再工程工具
  3. 软件管理和支持工具 :这类工具用于支持软件项目管理和人员管理活动,确保软件高质量完成。包括项目管理工具配置管理工具(涵盖版本控制 、变更管理、配置状态管理等功能)以及软件评价工具等。其中,配置管理工具明确包含版本控制工具,体现了分类中的内在联系,但课本将其独立归类为管理和支持工具的一部分。

!CAUTION

版本控制工具在软件工具分类中存在归属重叠问题,

  • 软件维护工具中,其作为版本管理工具的子类,用于软件交付后的维护阶段,例如管理版本变迁、处理代码和文档的维护活动(如VSS、CVS等工具)。
  • 软件管理及支持工具 中,配置管理工具作为核心组成部分,其功能描述包括版本控制、变更管理等。

版本控制工具既服务于维护阶段(如管理正式发布后的版本升级),也贯穿开发过程(如管理开发中的草稿版本和配置)。

项目管理工具

项目管理工具是辅助支撑项目管理工作 的软件工具,典型代表为Microsoft Project 。这类工具主要用于呈现进度计划、任务调度 等内容,其核心价值在于从成本、进度、资源等多个维度对项目进行全局管控。掌握项目管理工具的关键在于明确其功能边界:它能做什么、不能做什么。

具体而言,项目管理工具与开发工具存在本质区别。开发工具聚焦于软件开发流程的具体技术环节 ,例如在需求分析阶段使用工具进行UML建模(如通过Visual工具),在设计或编码阶段使用Delphi等工具完成编程任务。这些属于开发维度的活动,直接支撑技术实现过程。而项目管理工具属于管理维度,不涉及具体技术细节(如如何开展分析工作或指导设计),仅提供管控支撑,例如跟踪成本、分配资源或监控进度

例题

题目

软件系统工具的种类繁多,通常可以按照软件过程活动将软件工具分为( )。

答案:

B. 软件开发工具、软件维护工具、软件管理工具和软件支持工具

解析:

根据课本,软件工具按功能可划分为三类:软件开发工具软件维护工具软件管理及支持工具。其中,"软件管理及支持工具"在部分表述中被拆分为"软件管理工具"和"软件支持工具"。

  • 开发工具:用于需求分析、设计、编码与排错、测试等开发阶段。
  • 维护工具:用于交付后维护,如版本控制、逆向工程、文档分析等。
  • 管理与支持工具:包括项目管理、配置管理、软件评价等,确保项目顺利推进与质量保障。

软件过程管理

软件过程改进

CMMI

CMMI(能力成熟度模型集成)是软件过程改进 的核心体系,用于评估和提升组织的能力成熟度 。其本质是通过体系化方式 管控软件开发过程,确保过程有效且成熟,从而稳定产出高质量成果。若组织自身过程不成熟,难以保障产品效果。CMMI通过监管软件产出过程,实现质量保证目标,而非直接参与质量控制。

CMMI模式

CMMI分为阶段式和连续式 两种模式,两者在效果上本质一致,但企业更倾向采用阶段式。原因在于阶段式提供明确的等级评定规则,便于企业获取认证(如针对国外项目要求的等级证明)。国内企业常通过阶段式认证获取等级,以满足国际项目对组织过程成熟度的要求。

阶段式成熟度等级

阶段式从二级开始划分(一级为混乱级,通常不参与评定),共五级:

  • 二级(已管理级) :聚焦项目级可重复性,通过规范过程确保同类项目经验可传承。关键过程域包括需求管理、项目计划、配置管理、项目监督与控制等。
  • 三级(已定义级) :强调组织级文档化与标准化,将项目经验沉淀为组织过程资产。关键过程域涵盖需求开发、技术解决方案、组织级过程定义、集成项目管理等,确保人员变动不影响业务连续性。
  • 四级(定量管理级):引入量化管理,关注过程性能数据与项目指标的精确控制。关键过程域为组织级过程性能和定量项目管理。
  • 五级(优化级):侧重持续优化,通过因果分析推动过程改进。关键过程域包括组织级改革与实施、因果分析和解决方案。

(其中二级、三级最经常考察)

软件重用与再工程

软件重用概念

软件重用可划分为三个层次:

  • 知识重用 :较高维度的复用,涵盖开发经验 (如老程序员积累的项目经验)和应用领域知识(如医疗、金融行业的专业知识)。例如,同一行业多个甲方需求相似时,行业知识可直接复用,避免常见错误并提升项目效率。
  • 方法和标准的重用 :聚焦开发过程与规范,如敏捷开发等方法论 可在不同项目中复用;编码标准、行业标准化需求也可跨项目应用,确保开发一致性。
  • 软件成分的重用 :细化到具体元素,包括构建、代码片段、标准库、方法库等。常见软件元素涵盖应用领域知识、需求文档、设计经验、体系结构、源代码、测试用例等,直接支撑技术实现。

掌握软件重用的关键在于理解其层次划分与实现方式,明确不同维度的复用边界与价值,从而在实际开发中合理利用已有资源提升效率。

软件重用过程

软件重用的实现通过三种过程模型:

  • 组装模型 :类似搭积木,将已有组件组合成新系统
  • 类重用模型 :面向对象开发中,通过复用类生成新实例
  • 通用过程模型 :通过重用开发方法与过程(如开发流程、思想)实现整体复用。

软件重用的核心在于通过系统化流程复用已有软件元素 ,提升开发效率。其过程始于需求分析 ,需明确所需功能并识别可重用的软件构件。此阶段聚焦于判断哪些构件具备复用价值,例如评估功能通用性、与硬件的关联性及后续修改难度,而非仅关注功能实现本身。

接下来进入领域工程阶段,即开发可重用软件构件 。该过程包含三个关键环节:分析、开发与传播分析 环节需标识潜在可重用构件 ,重点考察其未来适用性;开发环节 则强调标准 化,包括设计统一的数据结构、接口协议和程序模板,确保构件的开放性与互操作性;传播 环节要求详细描述构件功能、使用条件及调用方式,便于后续共享。

构建构件库 是重用过程的基石,涉及构件的标识、构造、分类与存储 。构件库需对积累的构件进行系统化管理,其中分类是检索的前提 。分类模式分为三种:枚举分类采用树形目录结构分层组织构件;刻面分类通过多维度特性描述构件,支持灵活检索;属性值分类则基于单一属性(如功能或性能)进行划分。新版教程以属性值分类替代旧版的抄文本方式,后者易产生模糊查询结果。

检索构件 时,需依据分类体系查找并评估构件适用性 。若构件不完全匹配,需补充或修改后再组装。组装技术包括基于功能 的方式(通过子程序调用和参数传递)、基于数据 的方式(以核心数据结构为设计框架,如Jackson方法)及面向对象方式(利用继承与封装机制)。组装完成后,必须进行测试与调试,验证系统功能完整性,确保复用构件的可靠性。

软件重用环境由多个元素支撑:**构件库用于存储构件;构件库管理系统负责维护;检索系统支持高效查找;CASE工具辅助设计与开发。**这些元素共同构成可重用环境,保障整个重用流程的顺畅执行。理解此过程的关键在于把握各环节的衔接逻辑,从需求驱动到环境支撑,实现软件资产的高效复用。
需求分析
开发可重用的

软件构件(领域工程)
分析过程:

标识可重用的软件构件
开发过程:

标准的数据结构、

标准的接口协议、

程序模板
传播过程:

描述构件功能、

使用条件、接口、

实现方式等
构建构件库:

标识、构造、

分类和存储构件
三种典型分类模式:

□ 枚举分类(树形目录)

□ 刻面分类(多维度特性)

□ 属性值分类(单一属性)
检索软件构件

(分类便于检索)
补充/修改构件
组装构件:

□ 基于功能(子程序调用)

□ 基于数据(核心数据结构)

□ 面向对象(继承与封装)
测试与调试
完成系统

逆向工程

基本概念

逆向工程是正向工程的反向过程 ,本质是设计的恢复 。其典型应用包括硬件领域的手机拆解分析、军事领域的战机残骸研究,以及软件领域从可运行系统恢复设计层面信息。在软件开发中,逆向工程通常作为再工程的一部分,服务于系统重构。 再工程 是完整过程,包含三个关键步骤:通过逆向工程理解现有系统、考虑新需求、通过正向工程构建新系统。这一流程体现了从旧系统到新系统的完整转换过程。

逆向工程按抽象层次分为四个级别,从低到高逐步抽象。实现级 最接近代码层面,关注语法树、符号表和过程的设计表示 ,通过这些元素反推系统实现细节。结构级 关注程序分量间的相互依赖关系 ,表现为调用图、结构图等,展示小功能模块间的衔接。功能级 上升到程序段功能及其关系层面 ,涉及更大范围的完整功能衔接,如数据和控制流模型。领域级 达到需求分析层次,反映程序实体与应用领域概念的对应关系,表现为实体关系模型(ER图)和UML建模内容。这四个级别由具体到抽象,系统地恢复软件设计信息。

相关概念

  • 重构/重组 指在同一抽象级别上转换系统描述形式,不改变功能只优化内部实现。例如优化统计模块算法,保持功能不变但提升性能。

  • 设计恢复 与逆向工程常被混淆,前者是借助工具从程序中抽取设计信息的单步操作,后者是系统性地在更高抽象层次建立程序表示的完整过程。前者强调从程序抽象出设计信息,后者关注整体流程性能。

  • 多个设计恢复操作连贯起来形成逆向工程。

  • 正向工程 不仅恢复设计信息 ,还用这些信息改变或重构系统以改善质量

  • 再工程 (也称重构工程)则是对现有系统重新开发的全局过程,涵盖逆向工程、需求考虑和正向工程三个环节。

在实际应用中,逆向工程用于理解现有系统,再工程用于系统性改进,而重构则在不改变功能前提下优化内部结构。这三种技术相互配合,共同服务于软件系统的持续演化与质量提升。

!CAUTION

python 复制代码
# login_module.py
# 简单的用户登录模块,该模块包含核心功能:验证用户名/密码、处理登录失败锁定。
import time

class User:
    def __init__(self, username, password, failed_attempts=0):
        self.username = username
        self.password = password
        self.failed_attempts = failed_attempts
        self.locked_until = None

class AuthService:
    def __init__(self, user_db):
        self.user_db = user_db  # 模拟数据库字典:{username: User}
    
    def login(self, username, password):
        user = self.user_db.get(username)
        if not user:
            return False, "User not found"
        
        if user.locked_until and time.time() < user.locked_until:
            return False, "Account locked"
        
        if user.password == password:
            user.failed_attempts = 0  # 重置失败次数
            return True, "Login successful"
        else:
            user.failed_attempts += 1
            if user.failed_attempts >= 3:
                user.locked_until = time.time() + 300  # 锁定5分钟
            return False, f"Invalid password. Attempts left: {3 - user.failed_attempts}"
设计恢复

设计恢复是单步操作 ,仅使用工具从代码中自动抽取特定设计信息 ,不涉及多层抽象或业务分析。 其目标 是快速获得代码的"设计快照"(如UML图、依赖关系),用于文档生成或初步理解。 局限在于不验证设计是否符合业务需求,也不处理高层抽象(如领域规则)。

当前例子中,设计恢复可以通过使用 UML 生成工具自动生成一个 UML类图 ,该图仅显示结构级信息 如:AuthService 依赖 User 类(通过 user_db 字典存储);login 方法有输入参数和返回类型。

设计恢复到此结束 。工具不会分析: 为什么失败尝试阈值是3次(业务规则)锁定5分钟是否符合安全需求?(领域概念);密码硬编码在内存中是否有风险?(安全缺陷)。它只提供静态代码结构的抽象表示,没有后续验证或高层映射。

逆向工程

逆向工程是一个完整过程 ,在多个抽象层次 (实现级→领域级)逐步构建程序表示,包含分析、验证、需求映射。 目标在于恢复系统的设计意图,识别缺陷,并指导重构或文档重建。 基于之前定义的四个层次,给出完整过程。

实现级(代码细节分析)

用 AST 工具(如 LibCST)解析 login 方法:

  • 识别关键节点:条件分支(if user.locked_until...)、状态更新(user.failed_attempts += 1)。

  • 发现潜在缺陷:locked_until 使用浮点时间戳,但未处理时区问题(可能引发时序漏洞)。

    • 输出:AST 树 + 代码缺陷报告(例如:"硬编码的300秒锁定时间未参数化")。

步骤2: 结构级(模块依赖分析)

  • 操作 :用 Pydeps 生成调用图:
    • 揭示 AuthService 强依赖内存字典 user_db,未抽象数据库接口。
    • 识别耦合问题:User 类同时处理业务逻辑(失败计数)和状态存储,违反单一职责原则。
  • 输出 :依赖图 + 架构改进建议(例如:"应引入 UserRepository 接口解耦数据存储")。

步骤3: 功能级(业务流程建模)

  • 操作 :人工分析数据流,绘制活动图

    plaintext 复制代码
    [用户输入] → [验证用户存在?] → (否) → 返回"User not found"
                        ↓ (是)
               [检查账户锁定?] → (是) → 返回"Account locked"
                        ↓ (否)
               [验证密码] → (成功) → 重置失败计数 → 登录成功
                        ↓ (失败)
               [更新失败计数] → [是否≥3?] → (是) → 设置锁定时间 → 返回错误
                                     ↓ (否)
                                     返回剩余尝试次数
  • 洞察

    • 功能缺陷:锁定逻辑在多次失败后才触发,但未记录攻击IP(安全需求缺失)。
    • 数据流冗余:每次调用都需遍历 user_db,未缓存活跃用户。

步骤4: 领域级(需求映射与验证)

  • 操作:访谈业务方或分析需求文档,映射到领域模型:

    • 领域概念

      • "账户安全策略" 应包含:失败阈值、锁定时长、IP封锁(但代码仅实现前两者)。
      • "用户凭证" 应加密存储(但代码中 password 是明文)。
    • UML 用例图

      plaintext 复制代码
      +----------------+       +-----------------------+
      |   安全管理员   |       |      登录系统         |
      +----------------+       +-----------------------+
              |                        |
              |--- "配置安全策略" ---->| (缺失:代码无策略配置接口)
              |--- "查看登录审计" ---->| (缺失:代码无日志记录)
  • 洞察

    • 代码缺失关键领域需求:审计日志、动态策略调整。
    • 建议重构:将安全策略参数化,并添加日志模块。

最终输出:一份综合报告,包含:

  • 当前设计缺陷(如明文密码、缺乏审计)。
  • 重构路线图:
    1. 优先级1:加密密码(领域级需求)。
    2. 优先级2:添加 SecurityPolicy 配置类(结构级解耦)。
    3. 优先级3:集成日志模块(功能级扩展)。

本质 :这是一个迭代的认知过程 ,从代码细节出发,逐步上升到业务目标。工具(如Pyreverse)仅作为辅助,核心是人工洞察(例如:"为什么业务要求5分钟锁定?是否合规?")。

设计恢复常是逆向工程的第一步 (例如,先用Pyreverse生成类图,再进行高层分析)。 但关键区别 在于设计恢复停止于设计表示 (如"这是代码的UML图");逆向工程超越设计,追问"这个设计是否合理?如何适配业务?"。

例题

软件逆向工程就是分析已有的程序,寻求比源代码更高级的抽象表现形式。在逆向工程中得出信息的四个抽象层次中,( )包括反映程序各部分之间相互依赖关系的信息;( )包括反映程序段功能及程序段之间关系的信息。

选项

  • A 实现级
  • B 结构级
  • C 功能级
  • D 领域级

答案与解析

  • 第一个空(反映程序各部分之间相互依赖关系的信息)B 结构级
  • 第二个空(反映程序段功能及程序段之间关系的信息)C 功能级
抽象层次 描述
A 实现级 包括程序的抽象语法树、符号表、过程的设计表示
B 结构级 包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图、程序和数据结构图
C 功能级 包括反映程序段功能及程序段之间关系的信息,例如数据和控制流模型
D 领域级 包括反映程序分量或程序诸实体与应用领域概念之间对应关系的信息,例如实体关系模型

软件产品线

基本概念

软件产品线不是单一技术 :是领域工程、DSSA(特定领域软件架构)、软件架构 等技术的综合体 。 其本质一次构建,多次复用,将领域经验沉淀为可复用资产,而非每次从零开始。

例如在单一领域(如在线教育平台)深耕多年后,提取共性功能 形成公共通用版本 ,再针对不同客户需求快速增补个性化功能 ,避免重复开发。 示例:为A、B、C多家教育机构开发平台时,核心功能(如课程管理、用户注册)复用率达80%,仅需针对个别需求(如支付方式)定制。

双生命周期模型

领域工程 聚焦领域共性 ;产出领域需求模型、领域架构、可复用构件应用工程 聚焦客户个性化需求 。将领域工程的输出作为基础,增补定制功能生成新系统。

产品线建立方式

建立方式按跨度 (演化式、革命式)和基础(基于现有产品、全新产品线)划分:

建立基础 演化式(渐进改造) 革命式(推倒重来)
基于现有产品 最保守/低风险 • 将现有产品逐步演化成产品线 • 用新架构替代旧系统 • 适用:现有系统较规范、缺陷少 高风险 • 核心资源开发基于现有产品集 • 需彻底重构,但保留部分资产 • 适用:现有系统有重大缺陷
全新产品线 中风险 • 从零构建核心资源库 • 逐步适配现有需求 • 适用:行业规范成熟但无历史包袱 最高风险 • 开发满足所有预期需求的核心资源 • 适用:全新领域、高投入能力

软件形式化方法

软件开发方法

软件开发方法 指软件开发过程中遵循的步骤、办法和方法论思想,用于系统化解决问题。 类比于传统行业(如建筑)有"施工规范",软件行业则将开发流程命名为特定方法(如敏捷、瀑布)。

概念 定义 关键区别
开发方法 方法论思想(如"自顶向下"的哲学) 定义"如何思考"开发过程
开发模型 阶段关系(如瀑布模型的顺序阶段) 定义"如何组织"开发活动
  • 模型可能遵循某种方法(如迭代模型遵循增量开发思想);
  • 方法也可能指导模型选择(如敏捷方法催生Scrum模型)。

软件开发方法的分类维度

维度 分类 特点与典型示例 适用场景
开发风范 1. 自顶向下 2. 自底向上 3. 混合式 - 自顶向下 :从全局到局部(先设计整体医疗管理系统,再拆分子模块) - 自底向上 :从局部到整体(先实现登录/报告模块,再集成) - 混合式:两者结合(全局规划+局部迭代) 适合需求清晰的系统(自顶向下); 适合快速验证的原型(自底向上)
适应范围 1. 整体性方法 2. 局部性方法 - 整体性 :覆盖全流程(如自顶向下、瀑布模型) - 局部性:聚焦特定阶段(如原型法用于需求分析;面向对象分析仅用于设计阶段) 大型系统开发(整体性); 需求模糊的初期阶段(局部性)
性质 1. 形式化方法 2. 非形式化方法 - 形式化 :基于数学验证(如航空航天控制),严谨但难理解 - 非形式化:灵活宽松(如敏捷、迭代),易实践但缺乏严格验证 高安全领域(形式化); 互联网/快速迭代项目(非形式化)
  • 多方法混合使用:一个项目可同时用自顶向下(整体规划)+ 原型法(需求验证)+ 敏捷(迭代开发)。
  • 避免教条主义:根据项目特性(如安全要求、需求稳定性)选择方法组合。

形式化方法

本部分的重点应该在于对形式化方法的讲解。

传统的形式化方法严谨但难用 ,依赖数学论证(如Z语言、B方法),开发人员需理解复杂逻辑。 易陷入细节(如证明每行代码的正确性),导致开发效率低下;用户难参与 ,业务方无法理解数学符号,需求沟通成本高。 存在历史局限性曾因实用性低未普及(20世纪80-90年代)。

现代的发展改善了实用性。

改进方向 具体方案 价值
图形化语言结合 用UML、SysML等图形表示形式化逻辑(如状态图描述协议) 直观简洁,降低理解门槛 保留数学严谨性
CASE工具(计算机辅助软件工程) 工具示例:SpecTRM、Atelier B - 自动化验证代码数学性质 - 生成形式化规范文档 简化描述工作 自动检测逻辑漏洞(如死锁)

现代形式化方法的典型流程
通过
失败
需求
图形化建模工具
自动验证
生成代码
修正模型
部署

案例:航空控制系统用SysML建模 + CASE工具验证,确保飞行软件无逻辑错误。

现代化形式方法适用于高可靠性领域(航空航天、医疗设备、金融交易系统)。

!NOTE

考试高频考点

  • 形式化方法 vs 非形式化方法的核心区别(数学基础 vs 灵活实践)。
  • CASE工具的作用(自动化验证、简化描述)。
  • 形式化方法的改进方向(图形化 + 工具支持)。

净室软件工程

类比于芯片生产需在"无尘室"中进行,避免人体灰尘/皮屑影响产品;净室软件工程追求消除人为引入的错误 ,使软件"无先天缺陷"。 其核心目标 在于以合理成本 开发高品质软件,而非纯理论研究。

基本概述

维度 内容 关键说明
理论基础 函数理论 + 抽样理论 数学理论为根基,强调形式化验证
核心价值观 正确性验证(替代单元测试) 通过数学证明保证软件正确性
核心矛盾 - 声称"开发者不需要进行单元测试" - 但承认"仍需传统模块测试" 理论与实践存在张力
方法论本质 通过数学模型证明消除源头错误,而非依赖后期测试 从设计源头保障质量

净室工程主张用数学验证替代单元测试,但实际中无法完全摒弃模块测试。

关键技术手段

技术维度 具体方法 实践价值
开发模式 增量式多轮迭代开发 降低单次验证复杂度
结构设计 盒子结构(黑盒→状态盒→明盒) 逐步细化,保证每层正确性
质量保障 正确性验证(核心) 通过数学证明替代部分测试
统计控制 统计抽样方法 量化评估软件质量

局限性

问题类型 具体表现 现实影响
理论化过强 数学验证复杂,耗时长 仅适用于小规模关键模块
验证困难 难以对GUI、I/O等非确定性行为进行形式化证明 适用范围受限
实践矛盾 声称替代测试,但仍需模块测试 开发流程设计不自洽
团队适应性 要求开发者掌握高深数学知识 人才门槛高,普及困难

例题

"以下关于净室软件工程的描述中,不正确的是哪一个?"

A. 净室软件工程是一种以合理成本开发高质量软件的方法。

B. 净室软件工程无需进行传统的模块测试。

C. 净室软件工程的理论基础主要是函数理论和抽样理论。

D. 采用正确性验证,使得净室项目的软件质量有了极大的提高。

解析

  • 正确答案B(净室工程虽强调正确性验证,但仍需传统模块测试)。
  • 干扰项辨析
    • A:符合净室工程核心目标;
    • C:理论基础描述准确;
    • D:正确性验证是其质量保障核心。

净室工程不排斥所有测试 ,仅主张用数学验证替代部分单元测试; 考试中若出现"完全无需测试"类表述,必为错误选项。

相关推荐
雾江流3 小时前
小喵播放器 1.1.5| 视频超分提升画质,支持网页视频,B站番剧
音视频·软件工程
Coder_Boy_6 小时前
基于SpringAI的在线考试系统-企业级软件研发工程应用规范案例
java·运维·spring boot·软件工程·devops
卡奥斯开源社区官方6 小时前
Claude 4.5技术深析:AI编码重构软件工程的底层逻辑与实践路径
人工智能·重构·软件工程
浩子智控10 小时前
开源RPA选择
python·c#·软件工程
宇钶宇夕11 小时前
CoDeSys入门实战一起学习(五):CoDeSys V3 车库门控制编程全解析系列(手册基础第二篇)
运维·自动化·软件工程
simon_skywalker1 天前
软件工程(二) 软件开发模型与方法
软件工程
番茄灭世神1 天前
Git入门使用学习
git·gitee·软件工程·计算机专业入门
静听松涛1332 天前
中文PC端多人协作泳道图制作平台
大数据·论文阅读·人工智能·搜索引擎·架构·流程图·软件工程
2401_861277552 天前
中国电信星辰AI大模型有哪些主要功能
人工智能·云计算·软件工程·语音识别