代码中的软件工程--Menu项目分析
综述:
本文将以VS Code + GCC工具集为主要环境编译调试Menu课程项目案例,通过阅读分析源代码并结合代码分析其中的软件工程方法、规范或软件工程思想。本文参考文章见:https://gitee.com/mengning997/se/blob/master/README.md
编译调试Menu项目:
1.您的Mac上可能已经安装了Clang。要验证它是否正确,请打开macOS终端窗口,然后输入以下命令:
clang --version
2.如果未安装Clang,请输入以下命令以安装命令行开发人员工具
xcode-select --install
3.在.vscode文件夹下创建task.json文件,内容如下
{ "version": "2.0.0", "tasks": [ { "label": "test", "type": "shell", "command": "make", "args": [ "all" ], "group": "build", "presentation": { // Reveal the output only if unrecognized errors occur. "reveal": "silent" }, // Use the standard MS compiler pattern to detect errors, warnings and infos "problemMatcher": "$msCompile" } ] }
4.创建launch.json文件,内容如下
{ "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Debug", "program": "${workspaceFolder}/test", "args": [], "cwd": "${workspaceFolder}" } ] }
5.编译调试项目,第一步使用make命令进行编译。

6. ./test 运行我们的menu项目,进入到MENUOS界面

7.输入help命令,获取MENU菜单

8.运行version命令获取版本、time命令获取系统时间、quit命令退出系统。
MenuOS>>version version - MenuOS V1.0(Based on Linux 3.18.6)
MenuOS>>time time - Show System Time time:2020:10:4:14:44:9
MenuOS>>time time - Show System Time time:2020:10:4:14:44:9
9.单步调试项目:打一个断点,F5进入单步调试。

代码分析
1.代码规范和代码风格。
孟宁老师把代码的风格分成三重境界:一是规范整洁。遵守常规语言规范,合理使用空格、空行、缩进、注释等;二是逻辑清晰。没有代码冗余、重复,让人清晰明了的命名规则。做到逻辑清晰不仅要求程序员的编程能力,更重要的是提高设计能力,选用合适的设计模式、软件架构风格可以有效改善代码的逻辑结构,会让代码简洁清晰;三是优雅。优雅的代码是设计的艺术,是编码的艺术,是编程的最高追求。
1.1Menu项目中linktable.c中良好的注释

1.2Menu项目中Menu.c中良好的命名

2.模块化设计
在软件设计中最重要的就是模块话的设计。通过模块化的设计让系统内的各个部分保持相对对了,以便每一个部分可以被独立地进行设计和开发。模块化设计的原理是关注点分离,相当于把复杂的问题分解成一个个简单的问题。

test.c、test_reply.c、test_fork.c、test_exec.c为终端的四个版本,这四个版本既有相同的部分,又有不同的部分,项目将相同的部分抽离出来形成menu.c。menu.c使用linktable.c这一文件来对链表进行操作。
3.接口化设计
接口就是双方需要遵守的条约,只有遵守了条约才能使用这一功能。接口可以解决模块化中重复利用率低的问题,提高可重用性。

menu项目中linktable.h就封装了大量函数接口。
4.线程安全
如果代码的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,
而且其他的变量的值也和预期的是一样的,就是线程安全的。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、
静态变量只有读操作,而无写操作。若有多个线程同时执行读写操作、一般都需要考虑线程同步,否则就可能影响线程安全。
下面以linktable.c中的DeleteLinkTable函数为例子讲解线程安全:通过 pthread_mutex_lock(&(pLinkTable->mutex));
pthread_mutex_unlock(&(pLinkTable->mutex));来进行加锁解锁操作,保证来线程执行的安全性。
int DeleteLinkTable(tLinkTable *pLinkTable) { if(pLinkTable == NULL) { return FAILURE; } while(pLinkTable->pHead != NULL) { tLinkTableNode * p = pLinkTable->pHead; pthread_mutex_lock(&(pLinkTable->mutex)); pLinkTable->pHead = pLinkTable->pHead->pNext; pLinkTable->SumOfNode -= 1 ; pthread_mutex_unlock(&(pLinkTable->mutex)); free(p); } pLinkTable->pHead = NULL; pLinkTable->pTail = NULL; pLinkTable->SumOfNode = 0; pthread_mutex_destroy(&(pLinkTable->mutex)); free(pLinkTable); return SUCCESS; }
浙公网安备 33010602011771号