高级软件工程-课程笔记总结

532 阅读16分钟

高级软件工程-课程笔记总结

软件工程学习总结具体要求:总结您在课程中的学习收获和感想(如果有)总结课程学习的内容,可以聚焦到某一关键问题上谈谈您对软件工程的理解撰写一篇公开可以访问的博客文章,题目自拟,参考资料:代码中的软件工程 gitee.com/mengning997…

我在2022年上半年选修了高级软件工程的课程,从《工欲善其事,必先利其器》到《软件危机的前生后世》,每一节课都带给了我很大的收获和思考。我想在这篇博客中整理一下课程中学习的知识点,巩固课上所学的知识同时作为对期末考试的一次复习,并且方便日后需要这些知识时,还可以很方便地查询。

工欲善其事 必先利其器

VSCode

常用快捷键
  • 打开文件夹( Ctrl/⌘+O)和关闭文件夹工作区( Ctrl/⌘+K F)
  • 新建文件(Ctrl/⌘+N)、关闭文件(Ctrl/⌘+W)、编辑文件和保存文件(Ctrl/⌘+S)
  • 文件内搜索(Ctrl/⌘+F)
  • 关闭所有文件(Ctrl/⌘+K W)
  • 关闭已保存的文件(Ctrl/⌘+K U)
  • Ctrl+/用于单行代码注释和取消注释,Ctrl+Shift+A用于代码块注释和取消注释。
VSCode的优势
  • 专注于开发者“最常用”的功能,简洁聚焦
  • 进程隔离的插件模型:把插件放入单独的进程中,插件不会影响主进程代码的执行

  • UI渲染与业务逻辑隔离

  • 代码理解与调试:LSP(Language Server Protocol)协议和DAP协议

    • LSP协议:基于文本JSON,JSONRPC的协议。节制的设计,合理的抽象,周全的细节
  • VSCRD:Remote Development,方便远程开发

git

image.png

本地:
  • git init:新目录下创建版本库
  • git clone github.com//...... 克隆远端,在本地创建一个版本库
  • git init:初始化一个本地版本库
  • git status:查看当前工作区的状态
  • git add [FILES]:将文件添加到暂存区
  • git commit -m [xxx]:将暂存区代码提交到仓库
  • git log:查看提交记录
  • git reset -hard [commitid]:版本回退
  • git reflog:查看当前head之后的提交记录
远程
  • git clone:克隆一个仓库到本地一个新目录下

  • git fetch:下载一个远程存储库的数据对象等信息到本地存储库

    • git clone克隆整个仓库,包括版本更新;
    • git pull 拉取特定分支并和本地合并
    • git fetch 下载特定分支(默认master),不会进行合并,需要手动git merge
  • git push:将本地仓库更新到远程

  • git merge:合并两个或多个开发记录

  • git pull:从其他存储库或分支抓取并合并到当前存储库当前分支

合并:

默认合并方式为”快进式合并“

image.png

image.png

image.png

  • git checkout -b mybranch:创建新分支
  • git branch 切换分支
  • git checkout master:切换回主分支
  • git merge --no-ff mybranch:用--no-off方式合并
  • git rebase i [startpoint][endpoint]:重新整理一下提交记录

正则表达式:

  • “.”表示任意一个字符;
  • “?”表示前一个字符是否存在,也就是存在 0 次或 1 次;
  • “+”表示前一个字符出现一次或多次;
  • “*”表示前一个字符出现 0 次、1 次或多次
  • ”|“ 或
  • 要匹配字符串"aaah"中出现 3 到 5 次的 a,你的正则表达式将是 a{3,5}h;
  • 仅匹配字符串"haaah"与至少出现 3 次的字母 a,正则表达式将是/ha{3,}h;
  • 为了仅匹配"hah"中出现 3 次的字母 a,你的正则表达式将是/ha{3}h。
  • [aiu]是只匹配字符"a","i"或"u"的 character sets 字符集。
  • 字符集[0-5]匹配 0 和 5 之间的所有数字,
  • [^aeiou]排除元音的所有字符
  • 快捷方式\w 匹配字母数字[A-Za-z0-9_]
  • 快捷方式\W 与[^A-Za-z0-9_]相同
  • 快捷方式\d 搜索数字字符集[0-9]
  • 快捷方式\D 查找非数字字符,等于字符集[^0-9]
  • 快捷方式\c 表示大小写不敏感,\C 表示大小写敏感,比如/ignorecase\c, 这个正则表达式可以匹配”ignorecase”,"igNoreCase"和"IgnoreCase"
  • \s 搜索空格,还包括回车、制表符、换页和新行字符
  • \S 搜索非空格
  • 正则表达式是默认的是 greedy 贪婪匹配,可以使用?字符将其更改为 lazy 懒惰匹配。“titanic”匹配调整后的 t[a-z]*?i 正则表达式会返回["ti"]。注意这时字符“?”表示 lazy 懒惰匹配
  • 在方括号之外的正则表达式中插入字符“^”用于表示字符串的开头。美元字符“”表示字符串的末尾。如在"Rickyisfirstandcanbefound”查找开头的RickyRicky,查找结尾的found则为/found”表示字符串的末尾。如在"Ricky is first and can be found”查找开头的 Ricky 则为^Ricky,查找结尾的 found 则为/found
  • 正则表达式中"/"是表达式开始和结束的标记,“\”可以将后面出现的字符标记为特殊字符(对于开头应该是两个版本)
  • 捕获组来匹配字符串中连续出现三次的数字,每个数字由空格分隔,如 (\d+)\s\1\s\1。

软件科学概论

软件是什么

软件的基础结构
  • 顺序结构
  • 分支结构
  • 循环结构
  • 函数调用框架
  • 继承与对象组合
一些特殊机制
  • 回调函数:回调函数就是一个通过函数指针调用的函数,把函数的指针(地址)作为参数传递给另一个函数
  • 多态:同一个实例化变量在不同的实例对象上下文环境中执行不同的代码表现出不同的行为状态,而通过实例化变量调用实例对象的方法的那一块代码却是完全相同的
  • 闭包:一般用在将函数作为返回值时,该函数执行所需的上下文环境也作为返回的函数对象的一部分,这样该函数对象就是一个闭包。
  • 异步调用
  • 匿名函数

软件设计模式初步

设计模式组成
  • 该设计模式的名称
  • 该设计模式的目的,即该设计模式要解决什么样的问题;
  • 该设计模式的解决方案;
  • 该设计模式的解决方案有哪些约束和限制条件。
根据作用对象分为两类
  • 类模式:用于处理类与子类之间的关系,通过继承来建立,静态的。如模板方法
  • 对象模式:处理对象之间的关系,通过组合或聚合来实现,动态。组合关系比继承关系耦合度低,多数采用
根据完成任务类型来划分:
  • 创建型模式:单例模式、原型模式、建造者模式
  • 结构型模式:代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式
  • 行为型模式:模板方法模式、策略模式、命令模式、职责链模式、观察者模式等
常用设计模式
  • 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,典型的应用如数据库实例。
  • 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例,原型模式的应用场景非常多,几乎所有通过复制的方式创建新实例的场景都有原型模式。
  • 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。主要应用于复杂对象中的各部分的建造顺序相对固定或者创建复杂对象的算法独立于各组成部分。
  • 代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。代理模式是不要和陌生人说话原则的体现,典型的应用如外部接口本地化将外部的输入和输出封装成本地接口,有效降低模块与外部的耦合度。
  • 适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。继承和对象组合都可以实现适配器模式,但由于组合关系或聚合关系比继承关系耦合度低,所以对象组合方式的适配器模式比较常用。
  • 装饰(Decorator)模式:在不改变现有对象结构的情况下,动态地给对象增加一些职责,即增加其额外的功能。装饰模式实质上是用对象组合的方式扩展功能,因为比继承的方式扩展功能耦合度低。
  • 外观(Facade)模式:为复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问。
  • 享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。比如线程池、固定分配存储空间的消息队列等往往都是该模式的应用场景。
  • 策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。策略模式是多态和对象组合的综合应用。
  • 命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理.
  • 模板方法(TemplateMethod 模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。模版方法是继承和重载机制的应用,属于类模式。
  • 职责链(Chain of Responsibility)模式:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。通过这种方式将多个请求处理者串联为一个链表,去除请求发送者与它们之间的耦合。
  • 中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交 互的对象。如果把这种“网状结构”改为“星形结构”的话,将大大降低它们之间的“耦合性”,这时只要找一个“中介者”就可以了。在软件的开发过程中,这样的例子也很多,例如,在 MVC框架中,控制器(C)就是模型(M)和视图(V)的中介者,采用“中介者模式”大大降低了对象之间的耦合性,提高系统的灵活性。
  • 观察者(Observer)模式:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为,这样所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式。
七大原则
  1. 单一职责原则 (Single Responsibility Principle):定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
  2. 开放关闭原则 (OpenClosed Principle):软件应当对扩展开放,对修改关闭
  3. 里氏替换原则 (Liskov Substitution Principle):继承必须确保超类所拥有的性质在子类中仍然成立.子类可以扩展父类的功能,但不能改变父类原有的功能。
  4. 依赖倒转原则 (Dependence Inversion Principle):要面向接口编程,不要面向实现编程。 高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
  5. 接口隔离原则 (Interface Segregation Principle):不考
  6. 迪米特法则(Law Of Demeter):只与你的直接朋友交谈,不跟“陌生人”说话
  7. 合成复用原则(Composite/Aggregate Reuse Principle):在软件复用时,要尽量先使用组合或者聚合关系来实现,其次才考虑使用继承关系来实现。如果要使用继承关系,则必须严格遵循 Liskov 替换原则。通常类的复用分为继承复用和对象组合复用两种。
继承复用的缺点

继承复用有简单和易实现的优点。

  • 继承复用破坏了类的封装性。
  • 子类与父类的耦合度高。
  • 继承复用限制了复用的灵活性。
合成复用的优点

• 组合或聚合复用维持了类的封装性。 • 新旧类之间的耦合度低。 • 复用的灵活性高。

常见软件架构

三层架构

界面层,业务逻辑层,数据访问层

MVC 架构:
  • Model(模型)代表一个存取数据的对象及其数据模型。
  • View(视图)代表模型包含的数据的表达方式,一般表达为可视化的界面接口。
  • Controller(控制器)作用于模型和视图上,控制数据流向模型对象,并在数据变化时更新视图。控制器可以使视图与模型分离开解耦合。
MVVM 即 Model-View-ViewModel
  • 优点:
    • 低耦合。视图(View)可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的"View"上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变。
    • 可重用性。你可以把一些视图逻辑放在一个 ViewModel 里面,让很多 View 重用这段视图逻辑。
    • 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
    • 可测试。界面素来是比较难于测试的,测试可以针对 ViewModel 来写。
软件架构复用
  1. 克隆,完整地借鉴相似项目的设计方案,甚至代码,只需要完成一些细枝末节处的修改适配工作。
  2. 重构,构建软件架构模型的基本方法,通过指引我们如何进行系统分解,并在参考已有的软件架构模型的基础上逐步形成系统软件架构的一种基本建模方法
几种架构的分解方法
  • 面向功能的分解方法,用例建模即是一种面向功能的分解方法;
  • 面向特征的分解方法,根据数量众多的某种系统显著特征在不同抽象层次上划分模块的方法;
  • 面向数据的分解方法,在业务领域建模中形成概念业务数据模型即应用了面向数据的分解方法;
  • 面向并发的分解方法,在一些系统中具有多种并发任务的特点,那么我们可以将系统分解到不同的并发任务中(进程或线程),并描述并发任务的时序交互过程;
  • 面向事件的分解方法,当系统中需要处理大量的事件,而且往往事件会触发复杂的状态转换关系,这时系统就要考虑面向事件的分解方法,并内在状态转换关系进行清晰的描述;
  • 面向对象的分解方法,是一种通用的分析设计范式,是基于系统中抽象的对象元素在不同抽象层次上分解的系统的方法
软件架构风格与策略
  • 管道-过滤器
  • 客户-服务
  • P2P
  • 发布-订阅
  • CRUD
  • 层次化
架构的描述方法
  • 分解视图 Decomposition View :分解视图用软件模块勾划出系统结构,往往会通过不同抽象层级的软件模块形成层次化的结构。
  • 依赖视图 Dependencies View :展现了软件模块之间的依赖关系。
  • 泛化视图 Generalization View :展现了软件模块之间的一般化或具体化的关系
  • 执行视图 Execution View :执行视图展示了系统运行时的时序结构特点,比如流程图、时序图等。
  • 实现视图 Implementation View :实现视图是描述软件架构与源文件之间的映射关系。
  • 部署视图 Deployment View :部署视图是将执行实体和计算机资源建立映射关系。
  • 工作任务分配视图 Workassignment View :工作分配视图将系统分解成可独立完成的工作任务,以便分配给各项目团队和成员。
软件质量的三种视角
  • 产品视角:用户看到的产品质量和开发者看到的产品质量是不同的,我们将用户看到的产品质量称为外部质量;开发者看到的产品质量称为内部质量。
  • 过程视角:软件过程主要是指开发和维护的过程
  • 价值视角:项目的估值
几种重要的软件质量属性
  • 易于修改维护(Modifiability)
  • 良好的性能表现(Performance)
  • 安全性(Security)
  • 可靠性(Reliability) :可以通过防止或容忍缺陷的存在使软件更加可靠,一般通过缺陷检测和故障恢复两类方法来提高软件的可靠性。缺陷检测主要包括被动缺陷检测、主动缺陷检测和异常处理等
  • 健壮性(Robustness):很好地适应环境或具有故障恢复等机制
  • 易用性(Usability)
  • 商业目标(Business goals)

未完待续