高级软件工程学习心得
本学期选修了孟老师的高级软件工程这门课,相比于以前学过的软件工程这门课,打破了个人对于软件工程学习的一些刻板印象,在本门课程的学习过程中,不是从某一个管理系统开始入手,而是从简单的menu菜单作为切入点,一步一步的将工程化的思维带给同学们。
在本门课一共学习了一下几个章节:
一、工欲善其事必先利其器
这一章节主要讲解的是当前程序员必备的一些技能技巧和一些常用的软件,包括:Typing、VSCode、Git、Vim、正则表达式。
Typing
打字练习不展开多聊
VSCode
VSCode属于一款比较精简式切比较便利的一款编辑器,使用进程隔离的插件模型,以及功能比较强的的远程操作等等,可
以通过安装插件来支持C++,PHP、Python等语言,所以近年来VSCode用户也处于不断上升的状态。
- VSCode常用的快捷键
打开文件夹:ctrl+o
关闭文件夹:ctrl+K F
新建文件:ctrl+N、关闭文件:ctrl+w、保存文件:ctrl+s
文件内搜索:ctrl+F
关闭所有文件:ctrl+K W
文件资源管理器:ctrl + shift + E
源代码管理器: ctrl + shift + G
启动与调试: ctrl + shift + D
查找并运行所有命令:ctrl+shift+P
管理拓展插件:ctrl+shift+X
Git与版本控制
Git是当前应用最多的版本控制,掌握了Git,团队合作编程的方式的效率将大大提高。
- Git常见的快捷键
在Linux上安装Git sudo apt install git
在一个新建目录下创建版本库 git init
通过clone远端版本库从而在本地创建一个版本库 git clone https链接
查看工作区的状态 git status
将文件添加到暂存区 git add [file]
将暂存区的文件提交到仓库 git commit -m “注释”
查看当前head之前提交的记录便于回到过去 git log
回退 git reset -hard commit-id
查看当前HEAD之后的提交记录 git reflog
回退 git reset -hard commit-id
下载一个远端的存储库对象 git fetch
将本地数据更新到远程 git push
合并开发历史记录 git merge
从其它库抓取并合并到当前库 git pull
新建分支,转入到分支
git check -b mybranch
git branch
转入到master
git checkout master
git rebase 将本地代码合并,但不在远端出现合并记录
Vim编辑器
Vim是一款无差别的文本编辑器,是从vi发展出来的。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
- 练习题
1、将当前文件中xxx字符串全部替换为yyy字符串
从第一行,到最后一行,使用g进行全局替换
:1,$s/xxx/yyy/g
2、将当前文件的10-20行的代码注释掉
使用#号注释
:10,20s/^/#/g
使用//注释
:10,20s#^#//#g
3、将2-3行代码复制粘贴10次
2[space]
2yy
10p
正则表达式
正则表达式是一种对字符串操作的逻辑公式,可以简单快速的完成对字符串的控制。在这个知识点中比较难以掌握的是通配符和捕获组
- 通配符,使用{,}可以表示区间的数量,使用[]可以表示可以使用的字符
. 匹配任意一个字符
+ 查找出现一次获多次的字符
* 匹配零次或多次出现的字符
? 检查前一个字符是否存在都可
-
捕获组,使用捕获组可以复用、
将需要复用的区域用()括起来,然后使用数字来进行代替
二、工程化编程实战
在这一章主要是讲解了工程化软件编程的思想,通过使用menu项目作为切入点,一步一步的对该项目进行完成,完成相应的代码规范,改写适合的代码风格,并在最终达到工程化的标准。
工程化编程实战共分为五个部分讲解,第一部分讲的是良好的代码风格,第二部分讲的是模块化的基本思想,第三部分讲的是可重用软件设计,第四部分讲的是可重用软件涉及到的线程安全,第五部分讲的是一些细节补充。
在本章中学到了一些比较重要和软件开发过程中常常会用的知识点。
代码风格的原则
简明、易读、无二义性
编写高质量代码的基本方法
- 通过控制结构来简化代码
- 通过数据结构来简化代码
- 一定要有错误处理
- 注意性能优先的代价
- 拒绝修修补补要不断重构代码
模块化的基本原理
在软件系统设计时保持系统内各部分相对独立。以便于每一个部分可以被独立的进行设计和开发。
重要的原则在于:关注点的分离。类似于分治法
软件设计中的一些基本方法
- KISS原则
- 使用本地化外部接口提高代码的使用能力
- 先写伪代码的代码结构更好一些
接口规范包含的五个基本要素
- 接口的目的
- 接口使用前置条件
- 接口遵循的协议规范
- 接口使用后的效果
- 接口隐藏的质量属性
微服务接口使用REST API定义接口
- Get用来获取资源
- Post用来新建资源
- Put用来更新资源
- Delete用来删除资源
接口与耦合度之间的关系
- 公共耦合:共享数据区或变量名
- 数据耦合:通过显示的调用传递的基本数据类型
- 标记耦合:在软件模块之间仅通过显示的调用传递复杂的数据结构
通用接口定义的方法
- 参数化上下文:将全局变量作为参数传入接口
- 移除前置条件:将参数尽可能的泛化化
- 简化后置条件
可重入函数的基本要求
- 不为连续的调用持有静态数据
- 不返回指向静态数据的指针
- 所有数据都有函数的调用者提供
- 使用局部变量来保护全局变量
- 通过临界区互斥避免冲突
- 绝不调用任何不可重入函数
三、从需求分析到软件设计
在这一章当中,讲解了软件工程当中,从需求分析到软件设计的全过程的方法以及使用到的工具,从最开始的准确获得用户需求,到后面对提取到的需求进行对应的建模,在建模的过程又用到了一些比较常用的一些图,比如:用例图、类图等,最后将完善好的内容进行统一过程,绘制时序图等,形成最终的软件设计方案。
在本章学到的相关知识:
需求的类型
- 功能性需求
- 非功能性需求
- 设计约束
- 过程约束
高质量需求的特点
- 需求可测试
- 解决冲突
- 需求很有特点
需求分析的两类基本方法
- 原型化方法
- 建模的方法
用例的几个基本要素
- 是不是业务过程
- 是不是由某个参与者触发
- 是不是显性的或隐性的中止于某个参与者
- 是不是为某个参与者完成了有用的业务工作
用例的三个抽象层级
- 抽象用例
- 高层用例
- 拓展用例
统一过程的核心要义
- 用例驱动
- 以架构为中心
- 增量且迭代
四、软件科学基础概论
在这一章节中,主要是对于一些软件科学的基础理论和一些高级用法进行了讲解,在最开始学习了软件中的一些基本构成元素,包括对象,函数变量,同时从更深层次的指令,操作数,二进制符号进一步理解,探索了软件的本质。再进一步探索一些软件中的特殊机制和一些高级用法,包括回调函数,多态,闭包,异步调用,继承和对象组合等等。
随后,学习了软件的设计模式,我是第一次接触设计模式这个概念,所以很多相关的知识点都不算特别能够理解,掌握的也不是很全面,在后期还需要进一步的学习。
在本章学到的相关知识:
对象组合为什么要优于继承?
- 1、继承破坏了对象的封装性,对象组合没有
- 2、对象组合的耦合性更低
- 3、使用对象组合少了继承的一些约束,更加灵活
设计模式由哪些部分组成
- 该设计模式的名称
- 该设计模式的目的,即设计模式要解决什么样的问题
- 该设计模式的解决方案
- 该设计模式的解决方案有哪些约束和限制条件
设计模式的分类
- 按照作用对象来分
- 类模式
- 对象模式
- 按照可以完成的任务类型来分
- 创建型模式
- 结构型模式
- 行为型模式
常用的设计模式
- 单例模式
- 原型模式
- 建造者模式
- 代理模式
- 适配器模式
- 装饰模式
- 外观模式
- 享元模式
- 策略模式
- 命令模式
设计模式背后的设计原则
- 开闭原则,对拓展开放,对修改关闭
- 单一职责原则,模块化,一个模块对应一个功能
- Liskov替换原则,继承必须保证父类拥有的性质在子类中任然成立
- 依赖倒置原则,高级和低级不相互依赖,都依赖抽象,因为抽象层相对稳定
- 迪米特法则,只和朋友说话,类似本地化外部接口
- 合成复用原则,对象组合
MVC
- Model,数据
- View,视图,前端
- Controller,业务逻辑,中介者
MVVM的优点
- 低耦合
- 可重用性
- 独立开发
- 可测试
MVC和MVVM的区别
MVC中model发生变化时,M可以直接通知V,但是MVVM中M发生变化时,需要通过VM才能告知V。
数据解析中,MVC中的V需要用到C来进行解析,所以要同时拥有C和M,但是MVVM中,只需要拥有VM就可以。
软件架构复用方法
- 克隆
- 重构
软件架构模型的作用
- 从整体上理解整个系统
- 给使用者提供了一个高层视图
- 为项目的构建过程提供了一个蓝图
- 有助于理清系统演化的内部逻辑
架构分解的常用方法
- 面向功能分解
- 面向特征分解
- 面向数据分解
- 面向并发分解
- 面向事件分解
- 面向对象分解
软件架构的描述方法
- 分解视图:用软件模块勾画出系统结构,用例图
- 依赖视图:展示软件模块之间的依赖关系,关联图
- 泛化视图:展现软件模块之间一般化和具体化关系,如继承,类图
- 执行视图:展示系统运行时的时序结构,流程图,时序图
- 实现视图:描述软件架构与源文件之间的映射关系,包图
- 部署视图:将执行实体和计算机资源简历映射关系,构件图,网络拓扑结构
- 工作任务分配视图:将系统分解成可以独立完成的工作任务
五、软件危机和软件过程
在这一章节中,主要是讲解了关于软件危机的诞生以及应对软件危机所产生的一些有效的方式,显然软件危机的存在是没有尽头的,这是一个嵌套的过程,也许在某一个阶段能够产生一些应对当时软件危机的方法,但是,当随着软件的复杂性越来越高,这样的方法也没有办法保证时时刻刻的一劳永逸。
主要涉及到的是一个敏捷开发的统一过程,统一过程的核心要义在于用例驱动,以架构为中心,增量且迭代。敏捷开发又包括计划阶段和增量阶段,在敏捷开发的过程中,能够使得程序员开展软件工程项目的过程中,更加清晰有思路。于此同时,团队协作也是必要的,在敏捷开发中,有一个敏捷宣言就是解释的开发过程之间的注意要点,个体和互动高于流程和工具,工作的软件高于详尽的文档,客户合作高于合同谈判,响应变化高于遵循计划。
总的来说,学习完本门课程过后,对软件工程有了较为清晰的思路,如何设计软件,软件设计流程,软件设计的中应该注意的问题,以及什么样的设计方式能够使得软件更加高效,更加清晰易懂,更加便于更新迭代,有干货,也有实践,也是学会了一些平时用的少,但是比较使用的技巧,如发博客,使用git,使用vim等等。
参考资料《代码中的软件工程》https://gitee.com/mengning997/se