代码中的软件工程

目录

什么叫软件工程

工欲善其事必先利其器

VScode 

git

Vim

正则表达式

1、作用(正则表达式是一种字符串匹配的模式)

2、语法(普通字符+特殊字符)

代码中的软件工程

模块化的基本原理

模块化设计的常见方法

本地化外部接口的含义

接口的基本概念

接口的五个基本要素

通用接口定义的基本方法

可重入函数与线程安全

从需求分析到软件设计

什么是需求分析

为什么需求重要

获取高质量需求的方法

高质量需求的特点

需求类型

需求分析的两类基本方法

用例满足的四个必要条件

用例的抽象层级

用例建模的基本步骤

统一过程的核心要义

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

形成软件设计方案的基本方法

软件科学基础概论

软件中的一些特殊机制

设计模式

常见的设计模式

设计原则

开闭原则(Open Closed Principle,OCP)

Liskov替换原则(Liskov Substitution Principle,LSP)

依赖倒置原则(Dependence Inversion Principle,DIP)

单一职责原则(Single Responsibility Principle,SRP)

迪米特法则(Law of Demeter,LoD)

合成复用原则(Composite Reuse Principle,CRP)

创建型模式

单例模式

原型模式

建造者模式

结构型模式

代理模式

适配器模式

行为型模式

策略模式

命令模式

模板方法模式

职责链模式

中介者模式

常见的软件架构举例

三层架构

MVC

MVVM

软件架构的描述方法

分解视图

依赖视图      

泛化视图

执行视图

实现视图

部署视图

工作分配视图

软件过程模型

瀑布模型

原型化的瀑布模型

v模型

螺旋模型

PSP、TSP

团队强度和项目特点的关系

团队项目的基本策略

CMM/CMMI

敏捷宣言的核心思想

DevOps

总结

参考资料



什么叫软件工程

        当软件的规模越来越大,复杂度不断增加,软件项目开发维护过程中的问题就逐步暴露出来:软件产品质量低劣、软件维护工作量大、成本不断上升、进度不可控、程序人员无限度地增加。所以在 60 年代,“软件危机”的概念被提出来。

        为解决软件危机,由此出现了一门新兴的工程学科:软件工程。软件工程就是要用工程化的方法去规范软件开发,让项目可以按时完成,成本可控,指令有保证

工欲善其事必先利其器

VScode 

        快捷键:Ctrl+Shift+P调出VS Code命令行,Ctrl+~ 调出VS Code的终端,Ctrl/⌘+Shift+E 文件资源管理器,Ctrl/⌘+Shift+G 源代码管理,Ctrl/⌘+Shift+F 跨文件搜索,Ctrl/⌘+Shift+D 启动和调试,Ctrl/⌘+Shift+M 查看错误和警告,Ctrl/⌘+Shift+X 管理扩展插件。

git

git init # 初始化一个本地版本库
git status # 查看当前工作区(workspace)的状态
git add [FILES] # 把文件添加到暂存区(Index
git commit -m "wrote a commit log infro ” # 把暂存区里的文件提交到仓库
git log # 查看当前HEAD之前的提交记录,便于回到过去
git reset —hard HEAD^^/HEAD~100/commit-id/commit- id的头几个字符 # 回退
git reflog # 可以查看当前HEAD之后的提交记录,便于回到未来
git reset —hard commit-id/commit- id的头几个字符 # 回退

Vim

命令模式(Command mode), 用户刚刚启动vi /vim,便进入了命令模式。此状态下敲击键盘动作会被vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令
输入模式(Insert mode), 在命令模式下按下i就进入了输入模式,按ESC退出输入模式,切换到命令模式
底线命令模式(Last line mode), 在命令模式下按下 :( 英文冒号)就进入了底线命令模式。底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。基本的命令有q(退出程序 )、 w(保存文件)等。按ESC键可随时退出底线命令模式

正则表达式

1、作用(正则表达式是一种字符串匹配的模式)

数据验证:比如电话号码、邮箱等

替换文本:快速找到特定文本,用于替换

快速提取字符串:基于匹配原则,快速从文档中查找或提取子字符串

2、语法(普通字符+特殊字符)

普通字符

[abc] 匹配[...]的所有字符

[^abc] 取反,除了[...]的其他字符

[A-Z] 区间字母A到Z

. 匹配除(\n换行符 \r 回车符)的任何单个字符

\s \S 匹配所有,\s所有空白符,包括换行 \S非空白符,不包括换行

\w 匹配字母、数字、下划线

特殊字符

$ 结尾位置 (匹配$字符----\$)

^ 开始位置(匹配$字符----\^)

() 子表达式开始和结束(匹配字符----\(   和  \))

* 匹配零次或多次(匹配字符----\*)

+ 匹配一次或多次(匹配字符----\+)

? 匹配零次或一次(匹配字符----\?)

代码中的软件工程

什么样的代码是好代码?

一是规范整洁。遵守常规语言规范,合理使用空格、空行、缩进、注释等

二是逻辑清晰。没有代码冗余、重复,让人清晰明了的命名规则。做到逻辑清晰不仅要求程序员的编程能力,更重要的是提高设计能力,选用合适的设计模式、软件架构风格可以有效改善代码的逻辑结构,会让代码简洁清晰;

三是优雅。优雅的代码是设计的艺术,是编码的艺术,是编程的最高追求

模块化的基本原理

关注点的分离,每一个软件模块都将只有一个单一的功能目标,并相对独立于其他软件模块,使得每一个软件模块都容易理解容易开发,从而整个软件系统也更容易定位软件缺陷bug,整个系统的变更和维护也更容易

模块化设计的常见方法

KISS原则:一个函数或方法只做一件事 使用本地化外部接口来提高代码的适应能力 不要和陌生人说话 先写伪代码 设计通常为每一个程序组件提供一个框架,然后用专业知识来编写代码实现设计 一定要有错误处理

本地化外部接口的含义

我们的代码不是通过API直接调用外部的代码,而是在我们的代码中调用本地的外部接口,本地的外部接口再去调用外部代码

接口的基本概念

接口就是互相联系的双方共同遵守的一种协议规范,通常是通过定义一组API函数来约定软件模块之间的沟通方式

接口的五个基本要素

目的;前置条件;使用接口的双方遵守的协议规范;后置条件;隐含的质量属性

通用接口定义的基本方法

参数化上下文;移除前置条件;简化后置条件

可重入函数与线程安全

可重入的函数可能是线程安全的也可能不是线程安全的;在多个线程中并发使用时是线程安全的,但不同的可重入函数(共享全局变量及静态变量)在多个线程中并发使用时会有线程安全问题 不可重入的函数一定不是线程安全的

从需求分析到软件设计

什么是需求分析

需求分析是在获取需求的基础上进一步对软件涉及的对象或实体的状态、特征和行为进行准确描述或建模的工作

为什么需求重要

不完整的需求是导致项目失败的主要因素,需求过程的某些部分设计是大部分项目失败的原因,如果不尽早检测到需求错误,代价可能会很高

获取高质量需求的方法

采访利益相关者、回顾文档、研究当前系统、了解用户的任务、使用特定领域的策略、与当前和潜在用户进行头脑风暴

高质量需求的特点

Correct正确的、Consistent一致的、Unambigious无二义性的、Complete完整的、Feasible可行的、Relevant和主要目标相关、Testable可测试的、Traceable可追踪的

需求类型

功能要求:根据所需活动描述所需行为

质量要求或非功能性要求:描述软件必须具备的一些质量特征

设计约束:设计决策,例如平台或接口组件的选择

流程约束:对可用于构建系统的技术或资源的限制

需求分析的两类基本方法

原型化方法:很好地整理出用户接口方式

建模的方法:快速给出有关事件发生顺序或活动同步约束的问题,能够在逻辑上形成模型来整顿繁杂的需求细节

用例满足的四个必要条件

1.是一个业务过程

2.由某个参与者触发

3.为特定的参与者完成一个特定的业务任务

4.终止于某个特定参与者

用例的抽象层级

抽象用例:一个干什么、做什么或完成什么业务任务的动名词短语

高层用例:给用例的范围划定一个边界

扩展用例:将参与者和待开发软件系统为了完成用例所规定的业务任务的交互过程详细地描述出来

用例建模的基本步骤

从需求表述中找出用例 描述用例开始和结束的状态 对用例按照子系统进行分类,描述用例与用例、用例与参与者之间的上下文关系 进一步逐一分析用例与参与者的详细交互过程

统一过程的核心要义

用例驱动、以架构为中心、增量且迭代的过程 敏捷统一过程进一步将软件过程中每一次迭代过程划分为计划阶段和增量阶段

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

1.确定需求

2.通过用例的方式来满足这些需求

3.分配这些用例到各增量阶段

4.具体完成各增量阶段所计划的任务

形成软件设计方案的基本方法

分析是分解大问题变成易于理解的小问题 综合是将小问题的解决方案组合起来构建软件的整体解决方案

软件科学基础概论

软件中的一些特殊机制

回调函数
回调函数就是一个通过函数指针调用的函数。把函数的指针(地址)作为参数传递给另一个函数,当这个指针调用其所指向的函数时,就称这是回调函数。回调函数不是该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应

继承和组合
继承可以重用代码,但是破坏了代码的封装特性,增加了父类与子类之间的代码模块耦合,因此我们需要避免使用继承,在大多数情况下,应该使用对象组合替代继承来实现相同的目标

多态
允许将不同的子类类型的对象动态赋值给父类类型的变量,通过父类的变量调用方法在执行时实际执行的可能是不同的子类对象方法,因而表现出不同的执行效果

闭包
闭包是变量作用域的一种特殊情形,一般用在将函数作为返回值时,该函数执行所需的上下文环境也作为返回的函数对象的一部分,这样该函数对象就是一个闭包 函数和对其周围状态的引用捆绑在一起构成闭包,在JavaScript中,每当函数被创建,就会在函数生成时生成闭包

异步调用
Promise对象实际上是对回调函数机制的封装,也就是通过then方法定义的函数与resolve/reject函数绑定,简化了回调函数传入的接口实现,在逻辑上也更加通顺,看起来像是个同步接口

匿名函数
lamda函数是函数式编程中的高阶函数,在我们常见的命令式编程语言中常常以匿名函数的形式出现,比如无参数的代码块{ code },有参数的匿名函数往往会使用箭头函数 { x => code };

设计模式

本质是面向对象设计原则的实际运用总结出的经验模型

要解决的问题是用模块化来包容变化,使用模块化封装的方法,按照模块化追求的高内聚低耦合目标,借助于抽象思维对模块内部信息的隐藏并使用封装接口对外只暴露必要的可见信息

常见的设计模式

 •  单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,典型的应用如数据库实例
•  原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例,原型模式的应用场景非常多,几乎所有通过复制的方式创建新实例的场景都有原型模式。
•  建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。主要应用于复杂对象中的各部分的建造顺序相对固定或者创建复杂对象的算法独立于各组成部分。

设计原则

开闭原则(Open Closed Principle,OCP

软件应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed for modification)

Liskov替换原则(Liskov Substitution Principle,LSP

继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

依赖倒置原则(Dependence Inversion Principle,DIP

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象(High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions)。其核心思想是:要面向接口编程,不要面向实现编程

单一职责原则(Single Responsibility Principle,SRP

单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分(There should never be more than one reason for a class to change)

迪米特法则(Law of Demeter,LoD

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性

合成复用原则(Composite Reuse Principle,CRP

它要求在软件复用时,要尽量先使用组合或者聚合关系来实现,其次才考虑使用继承关系来实现

创建型模式

单例模式

某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例

原型模式

将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例,原型模式的应用场景非常多,几乎所有通过复制的方式创建新实例的场景都有原型模式

建造者模式

将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象

结构型模式

代理模式

为某对象提供一种代理以控制对该对象的访问,从而限制、增强或修改该对象的一些特性。典型的应用如外部接口本地化将外部的输入和输出封装成本地接口,有效降低模块与外部的耦合度。

适配器模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作,对象组合方式的适配器模式比较常用

行为型模式

策略模式

定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。策略模式是多态和对象组合的综合应用

命令模式

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开

模板方法模式

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤

职责链模式

将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链

中介者模式

定义一个中介对象来简化原有对象之间的交互关系 降低系统中对象间的耦合度,使原有对象之间不必相互了解。如控制器就是模型和视图的中介者,采用“中介者模式”大大降低了对象之间的耦合性,提高系统的灵活性

 改变通知给其他多个对象,从而影响其他对象的行为 这样所有依赖于它的对象都得到通知并被自动更新

举一个高温报警系统的例子

我们以高温预警系统为例来看看观察者模式的范例代码。高温预警系统是气象部门根据气象卫星获得相关的天气温度信息,当温度超过某一阈值时,向各个单位和个人发出高温警报通知,以及时做好高温防护措施。高温预警过程分析总结为如下几点:
  •  想要得到高温警报通知的对象订阅高温预警服务
  •  高温预警系统需要知道哪些对象是需要通知的。这需要预警系统维护一个订阅对象列表
  •  高温预警系统在温度达到阈值的时候,通知所有订阅服务的对象。如何通知呢?这需要订阅服务的对象具备接收高温警报通知的功能

 

常见的软件架构举例

三层架构

  • 表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
  • 业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
  • 数据访问层:主要看数据层里面有没有包含逻辑处理,实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。

MVC

Model代表一个存取数据的对象及其数据模型 View代表模型包含的数据的表达方式,一般表达为可视化的界面接口 Controller作用于模型和视图上,控制数据流向模型对象,并在数据变化时更新视图。控制器可以使视图与模型分离开解耦合

MVVM

把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model

软件架构的描述方法

分解视图

        分解是构建软件架构模型的关键步骤,分解视图也是描述软件架构模型的关键视图,一般分解视图呈现为较为明晰的分解结构(breakdown structure)特点。分解视图用软件模块勾划出系统结构,往往会通过不同抽象层级的软件模块形成层次化的结构。由于前述分解方法中已经明确呈现出了分解视图的特征,我们这里简要了解一下分解视图中常见的软件模块术语。  

依赖视图      

        依赖视图展现了软件模块之间的依赖关系。比如一个软件模块A调用了另一个软件模块B,那么我们说软件模块A直接依赖软件模块B。如果一个软件模块依赖另一个软件模块产生的数据,那么这两个软件模块也具有一定的依赖关系。

泛化视图

        泛化视图展现了软件模块之间的一般化或具体化的关系,典型的例子就是面向对象分析和设计方法中类之间的继承关系。值得注意的是,采用对象组合替代继承关系,并不会改变类之间的泛化特征。因此泛化是指软件模块之间的一般化或具体化的关系,不能局限于继承概念的应用。

执行视图

       执行视图展示了系统运行时的时序结构特点,比如流程图、时序图等。执行视图中的每一个执行实体,一般称为组件(Component),都是不同于其他组件的执行实体。如果有相同或相似的执行实体那么就把它们合并成一个

实现视图

        实现视图是描述软件架构与源文件之间的映射关系。

部署视图

        部署视图是将执行实体和计算机资源建立映射关系。

工作分配视图

        工作分配视图将系统分解成可独立完成的工作任务,以便分配给各项目团队和成员。

软件过程模型

瀑布模型

瀑布模型是一个过程活动的顺序结构,没有任何迭代。瀑布模型不能为处理开发过程中的变更提供任何指导意义,因为瀑布模型假定需求不会发生任何变化

原型化的瀑布模型

原型就是根据需要完成的软件的一部分,完成哪一部分是根据开发原型的目标确定,比较常见的有用户接口原型和软件架构原型

v模型

在瀑布模型基础上将需求分析和接受度测试、系统设计和系统测试、详细设计和单元测试结合起来,最后是产品,提高过程活动的内聚度

生死相依原则:创建一个对象和销毁一个对象的代码成对出现便于代码的组织和管理,V模型就是开始一个特定过程活动和评估该特定过程活动成对出现,从而便于软件开发过程的组织和管理

分阶段开发可以让客户在没有开发完成之前就可以使用部分功能,也就是每次交付系统的一小部分

分阶段开发的优点 在系统没有开发完成之前,开始进行交付和用户培训 频繁的软件发布可以让开发者敏捷的应对始料未及的问题 开发团队可以在不同的版本聚焦与不同的功能领域,从而提高开发效率 有助于提前布局抢占市场

螺旋模型

螺旋模型是一种演化软件开发过程模型,兼顾了快速原型的迭代的特征以及瀑布模型的系统化与严格监控。螺旋模型最大的特点在于引入了其他模型不具备的风险管理,使软件在无法排除重大风险时有机会停止,以减小损失

PSP、TSP

个体软件过程PSP可以帮助软件工程师在运用软件过程的方法和原则,借助于一些度量和分析工具,了解自己的技能水平,控制和管理自己的工作方式,使自己日常工作中的评估、计划和预测更加准确、更加有效,进而改进个人的工作表现

团队强度和项目特点的关系

项目失败最根本的原因是团队问题(缺乏有效的领导和管理、不能做出妥协、安排或不善于合作、缺少参与、拖拉与缺乏信息、质量低劣、功能多余、无效的组员互评)

团队项目的基本策略

计划先行 完成概念设计 选择开发策略 完成规模计算 完成时间计算 评估风险 建立策略文档 指定配置管理计划

CMM/CMMI

CMM/CMMI用于评价软件生成能力并帮助其改善软件质量的方法,成为了评估软件能力与成熟度的一套标准,它侧重于软件开发过程的管理及工程能力的提高与评估 CMM有两种通用的评估方法用以评估组织软件过程的成熟度:软件过程评估和软件能力评价 CMM主要应用在两个方面:能力评估(软件过程评估和软件能力评估)和过程改进

敏捷宣言的核心思想

个体和互动高于流程和工具

工作的软件高于详尽的文档

客户合作高于合同谈判

响应变化高于遵循计划

DevOps

DevOps是一组过程、方法与系统的统称,用于促进软件开发、技术运营和质量保障部门之间的沟通、协作与整合

总结

        以上内容是对一本好书---《代码中的软件工程》的总结,深入浅出地为我们介绍软件工程这一学科,收益匪浅。工欲善其事必先利其器,先给我们介绍了作为一个“码农”需要掌握的工具,VS CODE---被誉为宇宙第一的代码编辑器,轻量级,安装包小的同时还具有丰富的插件和扩展包,VIM,一个UNIX的文本编辑器,还有合作开发必备的git技巧,提高效率的正则表达式等等,正所谓磨刀不误砍柴工,在系统学习软件工程之前先学习工具的使用,才能使得后续的工作更顺利的开展。接着是通过一个menu的小项目来带我们进入代码中的软件工程,软件工程不能只停留在表面功夫,更应该注重实操和编程的能力,所以该章节用一个小项目向我们展示了一个规范的合理的通用的项目从0到1的过程,与此同时熟悉git的用法,了解项目开发的一些模块接口的规范使用。第二章是交给我们如何去开发一个模块,一个实用的小项目,第三章的需求分析阶段则更加倾向于教会我们在实际的生产中如何去确定一个项目的需求,这是至关重要的,我们所开发的代码程序最终是要为客户的需求所服务的,因此一个高质量的需求分析是非常重要的,之后又介绍了软件中的一些特殊函数和机制,还有设计模式,这是对面向对象设计中反复出现的问题的解决方案的总结和凝练,是一套较为成熟的经验模板,供我们借鉴和使用,之后还有常见的架构和软件的过程模型的介绍。总之通过对该课程系统的学习,对软件工程又有了新的更为透彻的理解,这不是一门理论科学而是一门应用科学,尤其对设计模式的理解,这不仅仅是一个模板,更是一种思想,我们要学习的就是这种编程的思想,而不是死记硬背模板。

参考资料

 代码中的软件工程 https://gitee.com/mengning997/se

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
评论

打赏作者

SA21225560

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值