代码中的软件工程之艺术

  摘要:本篇文章主要基于孟宁老师上课的内容以及menu实验代码完成。软件工程这门计算机类专业课的精髓、其重要思想常常浮现在优秀的开源项目里。在这一次的学习中,我主要对孟宁老师的menu案例进行分析,理解其中包含的软件工程思想。

参考链接:https://github.com/mengning/menu

 https://zhuanlan.zhihu.com/p/87864677          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

一、环境配置

1、C/C++的编译器有很多种,大家可自行选择,笔者这里选择开源的MinGW编译器。大家可以从sourceforge的mingw项目上下载64位的编译器,直接打开进行安装,安装好后配好环境变量。

 

 

 

然后开始安装C/C++扩展的,需要一段时间,请静心等待。等右下角的提示消失了,说明安装成功,此时重启VSCode让扩展生效。重启之后编写好hello.cpp文件,如下图。

 

2.配置编译器环境,,按快捷键Ctrl+Shift+P调出命令面板,输入C/C++,选择“Edit Configurations(UI)”进入配置。这里配置两个选项: - 编译器路径:D:/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/g++.exe。

配置完成后,此时在侧边栏可以发现多了一个.vscode文件夹,并且里面有一个c_cpp_properties.json文件,内容如下,说明上述配置成功。现在可以通过Ctrl+<`快捷键打开内置终端并进行编译运行了。

 

 

 

 二、模块化设计

让代码变成一个个独立的模块,将数据结构和操作放在独立的源代码中,这样每一个模块都将只有一个单一的功能目标,每一个模块也更容易被人理解。同时,如果发生bug,那么bug

只会局限在很小的模块内,影响范围也会很小,使得软件更容易定位bug、更容易维护。模块化设计,就是在考虑软件结构和流程的基础上,将各个功能与过程划分为不同的模块,同时协

调好各个模块之间的链接关系。这样的设计方法可以降低软件设计的难度与复杂度,同时有利于后期的维护。linktable.c中都是关于linktable相关操作的代码逻辑,Menu.c中实现了有关cmd的

相关逻辑,如添加、展示所有的cmd:

 

 尽管还是在同一个源代码文件中,但是已经在逻辑上做了切分。同时我们也应当看到,各模块之间不是完全独立的,他们之间存在着相互调用。

三、接口的可重用性

一般来说,接口规格包含五个基本要素:

1.接口的目的;

2.接口使用前所需要满足的条件,一般称为前置条件或假定条件;

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

4.接口使用之后的效果,一般称为后置条件;

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

可重用接口,则是其他程序员在重用这个接口时应该不需要了解这个接口内部代码的组织方式,只需要了解调用接口和生成的目标文件,就可以方便的将接口集成到自己的软件中。

 

 

SetPrompt用于设置输入信息;MenuConfig用于配置menu的参数并把cmd加入menu中;ExecuteMenu用于执行。

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

 

四、线程安全问题

  如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,

就是线程安全的。而如果多个线程同时运行,线程A修改了某个数据,切换到线程B执行,修改了同样的数据,但是再切换到线程A时,这个数据已经不是线程A修改完时的样子了,那么

这个进程就不是线程安全的。

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

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

 

 如果多个线程同时对一个链表执行删除及释放空间会导致冲突问题。但是,lock此时派上了大用处,其中有加锁pthread_mutex_lock和解锁pthread_mutex_unlock的过程,

这个过程可以保证一个线程在进行链表删除操作时,不会被其他线程所干扰,也即同时只能有一个线程来进行删除操作,从而保证了线程安全。

  我们再看,将链表作为了一种临界资源,按照信号量机制,对其进行互斥访问,即PV操作。比如在结构体的定义中。引入互斥的mutex变量。

 

 

五、总结

  首先感谢孟宁老师上课的精彩教学以及在Github上提供的源码,让我接触到了软件工程中的艺术之美。本次随笔,我们思考了代码注释整洁美观的问题,

考虑了模块化设计思想,并且学习到了应当注意可重用函数与线程安全的问题,这样我们才能在以后的码农之路上走的更远。

posted @ 2020-11-05 23:56  mxtw  阅读(227)  评论(0)    收藏  举报