在这一次的学习中,我主要对孟宁老师的menu案例进行分析,理解其中包含的软件工程思想。

源代码:https://github.com/mengning/menu

参考资料:https://gitee.com/mengning997/se/blob/master/README.md#%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B

一、环境配置

使用vscode+gcc工具集,编译器选择MinGW

vscode的安装不赘述

安装C/C++工具:

 

 编译器选择MinGW,记得安装完成之后要在环境变量PATH下天下MinGW的bin目录

在cmd中运行:

gcc -v
gdb -v

如下即为运行成功:

 

 

 

 

接下来对.vscode目录下的文件进行配置:

 

 编辑c_cpp_properties.json:将红框内路径设置为自己安装的MinGW中gdb.exe的路径

 

 编辑launch.json:将红框内路径设置为自己安装的MinGW中gdb.exe的路径

 

 编辑tasks.json:一是修改路径,二是将此项目的头文件加进去

 

 至此,环境配置结束,运行test.c成功:

 

二、模块化设计

模块化设计,就是在考虑软件结构和流程的基础上,将各个功能与过程划分为不同的模块,同时协调好各个模块之间的链接关系。这样的设计方法可以降低软件设计的难度与复杂度,同时有利于后期的维护。

在这个项目中我们可以清楚地看到模块化的思想:

 

 其中linktable.c主要是对数据结构的创建以及增删改查等操作;

menu.c则是主要负责一些动作以及代码逻辑的实现

test.c则是包含着最终的主函数

同时存在着linktable.h,menu.h头文件,其中定义着我们需要的接口。

 

 

当我们需要使用到linktable.c与menu.c里面的功能时,只需要引用对应的头文件,而不需要关注逻辑实现的细节,这儿很好的体现了模块化的思想。

 

三、可重用接口

接口主要是为了满足模块之间相互调用的需要,一般包含五个要素:

1.接口的目的

2.接口使用前需要满足的条件

3.使用接口的双方遵守的协议规范

4.接口使用之后的效果

5.接口所隐含的质量属性

具体看一看为menu子系统设置的接口:

在menu.h中:

 

 SetPrompt用于设置输入信息;

MenuConfig用于配置menu的参数并把cmd加入menu中;

ExecuteMenu用于执行。

然后再其他文件中就可以轻松调用menu系统中的内容,这时只需要关注接口使用本身而不需要关注其背后的细节部分:

 

 

四、线程安全

线程安全是指如果代码的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

线程安全主要体现在对链表的定义和操作上:

在链表的定义上我们引入了互斥的mutex:

 

 在对链表的操作上会通过加锁与解锁的操作保证线程安全,比如在delete操作中:

 

 比如在add操作中:

 

 当然,对于读操作,因为本身没有对链表内容有更改,所以就没有必要加锁解锁了。