Skip to content
Go back

📖高级软件工程学习总结

Published:  at  10:46 PM

学习收获

课程概述

这个学期选修了孟宁老师的高级软件工程课程,主要学习内容是《代码中的软件工程》。课程内容由浅入深,包括:

通过课堂讲授与课后编程实践相结合的方式,让我对软件工程有了更深刻的理解和掌握。

认识的转变

以前的误解

现在的认识

软件工程不仅仅是一门课程,更是一种思想体系。它提供了系统化的问题分析和处理方法,其应用范围远超出课程本身的范畴,是一个综合性的问题解决方法论。

以下将对课程学习内容进行系统总结,以便后续复习。

工欲善其事必先利其器

Visual Studio Code

常用快捷键

功能快捷键
打开文件夹Ctrl/⌘+O
关闭文件夹工作区Ctrl/⌘+K F
新建文件夹Ctrl/⌘+N
关闭文件Ctrl/⌘+W
编辑文件和保存文件Ctrl/⌘+S
文件内搜索Ctrl/⌘+F
关闭所有文件Ctrl/⌘+K W
关闭已保存的文件Ctrl/⌘+K U
单行注释Ctrl+/
块注释Ctrl+Shift+/
文件资源管理器Ctrl/⌘+Shift+E
源代码管理Ctrl+Shift+G
跨文件搜索Ctrl/⌘+Shift+F
启动和调试Ctrl/⌘+Shift+D
查找并运行所有命令Ctrl/⌘+Shift+P
查看错误和警告Ctrl/⌘+Shift+M
管理扩展插件Ctrl/⌘+Shift+X
切换集成终端Ctrl+`

代码理解和调试桥梁

用于代码理解和调试的第三方插件与VS Code主进程之间的桥梁:

Git

Git 本地常用命令

命令说明
git init在一个新建的目录下创建版本库
git status查看当前工作区的状态
git add Files把文件添加到暂存区
git commit -m "提交说明"把暂存区里的文件提交到仓库
git log查看当前HEAD之前的提交记录,便于回到过去
git reset --hard HEAD^^/HEAD-100/commit-id/commit-id的前几个字符回退版本
git relog可以查看当前HEAD之后的提交记录,便于回溯
git reset --hard commit-id/commit-id的头几个字符回退
git checkout 分支名切换分支

Git 远程版本库常用命令

命令说明
git clone 仓库地址通过clone远端的版本库从而在本地创建一个版本库
git fetch 仓库地址下载一个远程存储库数据对象等信息到本地存储库
git push 仓库地址将本地存储库的相关数据对象更新到远程存储库
git merge 分支名将目标分支合并到当前分支中,并自动进行新的提交,如果不想提交,可以加 --no-commit后缀

团队项目中的分叉合并

建议团队项目的每一个开发者都采用的工作流程大致如下:

  1. 克隆或同步最新的代码到本地存储库
  2. 为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制
  3. 在该分支上完成某单一功能模块或代码模块的开发工作
  4. 最后,将该分支合并到主分支

注意: Git默认的合并方式为快进式合并,会将分支里commit合并到主分支里,合并成一条时间线,与我们期望的呈现为一段独立的分支线段不符,因此合并时需要使用--no-ff参数关闭”快进式合并”

Vim

基本操作

Vim有三种主要模式:

常用光标移动命令:

命令说明
h,j,k,l左下上右移动光标
n向后移动n个字符
0 或 Home移动到行首
$ 或 End移动到行尾
H移动到屏幕最上方一行
M移动到屏幕中央一行
L移动到屏幕最下方一行
G移动到文件末尾
nG移动到第n行
gg移动到文件开头
n向下移动n行

删除操作

命令说明
dd删除当前行
ndd删除当前行及向下n行

复制粘贴

命令说明
yy复制当前行
p粘贴到光标下一行
P粘贴到光标上一行

撤销和重做

命令说明
u撤销上一个操作
Ctrl+r重做上一个操作

搜索

命令说明
/word向下搜索word
?word向上搜索word
n下一个搜索结果
N上一个搜索结果

替换

替换命令格式::n1,n2s/word1/word2/g

常用替换命令:

其他命令:

正则表达式

匹配模式

常用语法

语法说明
/vim中开启正则表达式
. * ? |基本元字符
{3,5}限定符
[a-z] [abc] [^]字符类
\d \D \w预定义字符类
*?开启懒惰模式
()捕获组

二、工程化编程实战

代码的风格原则:简明、易读、无二意性

编写高质量代码的基本方法

  1. 通过控制结构简化代码
  2. 通过数据结构简化代码
  3. 一定要有错误处理
  4. 性能优先策略背后隐藏的代价
  5. 拒绝修修补补,要不断重构代码

模块化软件设计

基本概念

软件设计中的基本方法

KISS(Keep It Simple & Stupid)原则

使用本地化外部接口来提高代码的适应能力,先写伪代码的代码结构更好一些。

消费者和生产者重用

消费者重用是指软件开发者在项目中重用已有的一些软件模块代码,以加快项目工作进度。

接口的基本概念

接口是互相练习的双方共同遵守的一种协议规范。在软件系统内部,一般通过定义一组API函数来约定软件模块之间的沟通方式。

接口规格的五个基本要素

  1. 接口的目的
  2. 接口使用前所需要满足的条件(前置条件或假定条件)
  3. 使用接口的双方遵守的协议规范
  4. 接口使用之后的效果(后置条件)
  5. 接口所隐含的质量属性

RESTful API

HTTP方法用途
GET获取资源
POST新建资源(也可以用来更新资源)
PUT更新资源
DELETE删除资源

接口与耦合度的关系

耦合度类型

  1. 公共耦合(紧密)

    • 软件模块之间共享数据区或变量名
    • 接口定义不是通过显式调用,而是隐式共享数据区域或变量名
  2. 数据耦合(松散)

    • 软件模块之间仅通过显式调用传递基本数据类型
  3. 标记耦合(松散)

    • 软件模块之间通过显式调用传递复杂的数据结构(结构化数据)
    • 耦合度比数据耦合高,但比公共耦合低

通用接口定义的基本方法

可重入的函数不一定是线程安全的,不可重入的函数一定不是线程安全的

微服务的概念

  1. 由一系列独立的微服务共同组成软件系统的架构模式

  2. 每个微服务:

    • 单独部署
    • 运行在自己的进程中
    • 拥有独立的运行环境和软件堆栈
  3. 特点:

    • 为独立的业务功能开发
    • 分解到最小可变产品(MVP)
    • 通过RESTful API接口方式封装
    • 分布式管理
    • 强调隔离性
    • 通过前端应用或API网关聚合各微服务

微服务架构可简单概括为:通过模块化思想垂直划分业务功能

三、从需求分析到软件设计

用例

用例的核心概念中首先它是一个业务过程,经过逻辑整理抽象出来一个业务过程,这是用例的实质。

用例的几个基本要素

  1. 一个用例应该由业务领域内的某个参与者所触发
  2. 用例必须能为特点的参与者完成一个特定的业务任务
  3. 一个用例必须终止于某个特定参与者,也就是特定参与者明确地或者隐含地得到了业务任务完成的结果

用例的三个抽象层级

  1. 抽象用例:只要用一个干什么、做什么或完成什么业务任务的动名词短语,就可以非常精简地指明一个用例。
  2. 高层用例:需要给用例的范围划定一个边界,也就是用例在什么时候什么地方开始,以及在什么时候什么地方结束。
  3. 扩展用例:需要将参与者和待开发软件系统为了完成用例所规定的业务任务的交互过程一步一步详细地描述出来,一般我们使用一个两列的表格将参与者和待开发软件系统之间从用例开始到用例结束的所有交互步骤都列举出来。

用例建模的基本步骤

  1. 从需求表述中找出用例,往往是动名词短语表示的抽象用例
  2. 描述用例开始和结束的状态,用TUCBW和TUCEW表示的高层用例
  3. 对用例按照子系统或不同的方面进行分类,描述用例与用例、用例与参与者之间的上下文关系,并画出用例图
  4. 进一步逐一分析用例与参与者的详细交互过程,完成一个两列的表格将参与者和待开发软件系统之间从用例开始到用例结束的所有交互步骤都列举出来扩展用例

准确提取用例的基本方法

  1. 从需求中寻找业务领域相关的动名词和动词短语,比如做什么事、什么事情必须完成、或者执行某任务等。

  2. 验证这些业务领域相关的动名词和动名词短语到底是不是用例。验证业务领域相关的动名词或动名词短语是不是用例的标准是满足四个必要条件:

    • 它是不是一个业务过程
    • 它是不是由某个参与者触发开始
    • 它是不是显式地或隐式地终止于某个参与者
    • 它是不是为某个参与者完成了有用的业务工作
  3. 在需求中识别出参与者、系统或子系统

参与者会触发某个用例开始,用例也会显式地或隐式地终止于某个参与者,用例会属于系统或子系统。

面向对象分析涉及的基本概念

对象和属性之间有依附关系,属性用来描述对象或存储对象的状态信息。

由于对象能够独立存在,那么对象的创建必须是通过显式地或隐式地调用构造过程。

继承关系

表达着两个概念之间具有概括化/具体化的关系。一个概念比另一个概念更加概括/具体。一般用三角形箭头连线表示两个类之间的继承关系。

聚合关系

聚合关系表示一个对象是另一个对象的一部分的情况。比如发动机引擎是小汽车的一部分。也被称为”部分与整体”的关系。

聚合关系使用一个平行四边形的箭头表示。

关联关系

关联关系表示继承和聚合以外的一般关系,是业务领域内特定的两个概念之间的关系。

业务领域建模的基本步骤

  1. 收集应用业务领域的信息。聚焦在功能需求层面,也考虑其他类型的需求和资料
  2. 头脑风暴,列出重要的应用业务领域概念,给出这些概念的属性,以及这些概念之间的关系
  3. 给这些应用业务领域概念分类。分别列出哪些是类、哪些属性和属性值、以及列出类之间的继承关系、聚合关系和关联关系
  4. 将结果用UML类图画出来

反范式化总结

使用双向引用来优化你的数据库架构,前提是你能接受无法原子更新的代价。

可以在引用关系中冗余数据到one端或N端。

在决定是否采用反范式化时需要考虑下面的因素:

瀑布模型

最基本的过程模型,它把整个软件过程按顺序划分成了需求、设计、编码、测试和部署五个阶段。

统一过程的核心要义是用例驱动、以架构为中心、增量且迭代的过程。用例驱动就是我们前文中用例建模得到的用例作为驱动软件开发的目标;以架构为中心的架构是后续软件设计的结果,就是保持软件架构相对稳定,减小软件架构层面的重构造成的混乱。

敏捷统一过程的四个关键步骤

  1. 确定需求
  2. 通过用例的方式来满足这些需求
  3. 分配这些用例到各增量阶段
  4. 具体完成各增量阶段所计划的任务

敏捷统一过程的增量阶段

在每一次增量阶段的迭代中,都要进行从需求分析到软件设计实现的过程,具体敏捷统一过程将增量阶段分为五个步骤:

  1. 用例建模
  2. 业务领域建模
  3. 对象交互建模
  4. 形成设计类图
  5. 软件的编码实现和软件应用部署

对象交互建模的基本步骤

  1. 找出关键步骤进行剧情描述
  2. 将剧情描述转换成剧情描述表
  3. 将剧情描述表转换成序列图

四、软件科学基础理论

软件的基本结构

顺序结构

最简单的程序结构,也是最常用的程序结构。只要按照解决问题的顺序写出相应的语句就行,它的执行顺序是自上而下,依次执行。

分支结构

在顺序结构的基础上,利用影响标志寄存器上标志位的质量和跳转质量组合起来,借助于标志寄存器或特定寄存器暂存条件状态实现分支结构。

循环结构

顺序结构和分支结构的组合形成的更为复杂的程序结构,是指在程序中需要反复执行某个功能而设置的一种程序结构。

回调函数

回调函数是一个面向过程的概念,是代码执行过程的一种特殊流程。回调函数就是一个通过函数指针调用的函数。把函数的指针(地址)作为参数传递给另一个函数,当这个指针调用其所指向的函数时,就称这是回调函数。

设计模式的组成部分

  1. 设计模式的名称
  2. 设计模式的目的(即要解决什么问题)
  3. 设计模式的解决方案
  4. 设计模式的解决方案有哪些约束和限制条件

设计模式的分类

根据模式是主要用于类上还是主要用于对象上来划分,可以分为:

类模式

用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来了。

对象模式

用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具动态性。

由于组合关系或聚合关系比继承关系耦合度低,因此多数设计模式都是对象模式。

常用的设计模式

创建型模式

结构型模式

行为型模式

设计模式背后的设计原则

  1. 开闭原则
  2. Liskov替换原则
  3. 依赖倒置原则
  4. 单一职责原则
  5. 迪米特法则
  6. 合成复用原则

软件架构模型

软件架构模型是在高层抽象上对系统中关键要素的描述,而且表现出抽象的层次结构。构建软件架构模型的基本方法就是在不同层次上分解系统并抽象出其中的关键要素。

分解的常见方法

  1. 面向功能的分解方法:用例模型即是一种面向功能的分解方法
  2. 面向特征的分解方法:根据系统显著特征在不同抽象层次上划分模块
  3. 面向数据的分解方法:在业务领域建模中形成概念业务数据模型
  4. 面向并发的分解方法:将系统分解到不同的并发任务中
  5. 面向事件的分解方法:处理大量事件和状态转换关系
  6. 面向对象的分解方法:基于系统中抽象的对象元素进行分解

软件架构风格与策略

常见架构风格

  1. 管道-过滤器风格:面向数据流的软件体系结构,典型应用是编译系统。

  2. 客户机-服务器结构:客户代码通过请求和应答方式访问服务代码。

    • 函数调用和返回值
    • socket中的sendrecv
    • HTTP中的get请求和响应
  3. P2P结构:每个构件既是客户端又是服务端,形成对等网络结构。

  4. 发布-订阅

    • 两类构件:发布者和订阅者
    • 事件触发通知机制
    • 观察者模式是典型实现
  5. CRUD架构

    • Create(创建)
    • Read(读取)
    • Update(更新)
    • Delete(删除) 适用于ERP、CRM等信息系统。
  6. 层次化架构:从垂直纵深角度组织软件单元,形成服务层次。

MVC结构

核心组成

  1. 模型(Model)

    • 封装应用程序状态
    • 响应状态查询
    • 实现应用程序功能
    • 通知视图改变
  2. 视图(View)

    • 解释模型
    • 处理模型更新请求
    • 发送用户输入给控制器
    • 允许控制器选择视图
  3. 控制器(Controller)

    • 定义应用程序行为
    • 用户动作映射成模型更新
    • 选择响应的视图

软件架构的描述方法

  1. 分解视图:勾画系统结构层次
  2. 依赖视图:展现模块间依赖关系
  3. 泛化视图:展现模块间一般化或具体化关系
  4. 执行视图:展示系统运行时序结构
  5. 实现视图:描述架构与源文件映射关系
  6. 部署视图:建立执行实体与计算资源映射
  7. 工作分配视图:分解独立工作任务

高质量软件的特征

质量维度

关键质量属性

五、软件危机和软件过程

软件危机

软件生命周期

  1. 分析
  2. 设计
  3. 实现
  4. 交付
  5. 维护

团队的基本要素

  1. 团队规模
  2. 团队的凝聚力
  3. 团队协作的基本条件

敏捷宣言

构件软件产品

驱动代码

调用或触发特定软件模块执行的测试程序,通过测试用例模拟模块执行上下文。

桩代码

模拟缺失软件模块的特殊程序,使依赖模块能正常测试执行。

参考链接

  1. 软件工程: 《代码中的软件工程》(gitee.com)
  2. Welcome to Mengning homepage. (ustc.edu.cn)

Suggest Changes

Previous Post
🖥️海力士Adie内存超频
Next Post
📖汽车软件工程Lab