代码中的软件工程--menu项目学习笔记

 

  在这堂课的学习中,孟宁老师以menu程序为例,指出在实际工程中,哪些地方会用到软件工程的思想。与未来工作接轨,让我们在编写代码时,要注意将其工程化,为未来工作打下良好的基础。感谢孟老师的辛勤指导!

 本文参考孟老师的文章:https://gitee.com/mengning997/se/blob/master/README.md

 

一、C++编译调试环境配置

1.安装vscode

2.安装 C/C++ 插件

 

 

 

 

 

 

 

 

 

3.C++编译器和调试器

  C++编译器和调试器的编译器和调试器有很多,这里选择minGW。在下载完成后,进行安装,秘诀就是闭着眼睛,一直按下一步。在安装完成后,还要配置一下环境变量。

 

 4.环境变量配置:

 

 

 

配置完成后,win+r,输入cmd,输入命令gcc -v、g++ -v 查看是否安装成功。

 

 5.Code Runner 插件安装

 

安装好Code Runner之后,打开你所要运行的文件,有多种方式来快捷地运行你的代码:

  • 键盘快捷键 Ctrl+Alt+N
  • 快捷键 F1 调出 命令面板, 然后输入 Run Code
  • 在编辑区,右键选择 Run Code
  • 在左侧的文件管理器,右键选择 Run Code
  • 右上角的运行小三角按钮

 

6.运行一个cpp文件,以helloworld为例:

终端-> 配置默认生成任务->

 

 

终端->运行生成任务

 

 

7. 扩展一下,运行test.c  menu.c

 

二、模块化设计

1. 模块化设计的基本原理
  模块化设计,简单地说就是程序的编写不是开始就逐条录入计算机语句和指令,而是首先用主程序、子程序、子过程等框架把软件的主要结构和流程描述出来,并定义和调试好各个框架之间的输入、输出链接关系。逐步求精的结果是得到一系列以功能块为单位的算法描述。以功能块为单位进行程序设计,实现其求解算法的方法称为模块化。模块化的目的是为了降低程序复杂度,使程序设计、调试和维护等操作简单化。改变某个子功能只需相应改变相应模块即可。
  关注点的分离在软件工程领域是最重要的原则,我们习惯上称为模块化,翻译成我们中文的表述其实就是“分而治之”的方法。
  关注点的分离的思想背后的根源是由于人脑处理复杂问题时容易出错,把复杂问题分解成一个个简单问题,从而减少出错的情形。
2. 模块化程度
  一般通过“耦合度”和“内聚度”来衡量模块化的程度。
  ①耦合度:是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。一般可以分为紧密耦合、松散耦合和无耦合。一般在软件设计中我们追求松散耦合。

   ②内聚度:标志一个模块内部各成分彼此结合的紧密程度。理想的内聚是功能内聚,也就是一个软件模块只做一件事,只完成一个主要功能点或者一个软件特性。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include <pthread.h>
 4 #include"linktable.h"
 5 
 6 /*
 7  * LinkTable Type
 8  */
 9 struct LinkTable
10 {
11     tLinkTableNode *pHead;
12     tLinkTableNode *pTail;
13     int            SumOfNode;
14     pthread_mutex_t mutex;              //mutex:互斥
15 
16 };
17 
18 
19 /*
20  * Create a LinkTable
21  */
22 tLinkTable * CreateLinkTable(){
23 }
24 
25 /*
26  * Delete a LinkTable
27  */
28 int DeleteLinkTable(tLinkTable *pLinkTable){        
29 }
30 
31 /*
32  * Add a LinkTableNode to LinkTable
33  */
34 int AddLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode){    
35 }
36 
37 /*
38  * Delete a LinkTableNode from LinkTable
39  */
40 int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode){        
41 }
42 
43 /*
44  * Search a LinkTableNode from LinkTable
45  * int Conditon(tLinkTableNode * pNode);
46  */
47 tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args){
48 }
49 
50 /*
51  * get LinkTableHead
52  */
53 tLinkTableNode * GetLinkTableHead(tLinkTable *pLinkTable){
54 }
55 
56 /*
57  * get next LinkTableNode
58  */
59 tLinkTableNode * GetNextLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)

  LinkTable模块实现了对menu的增删改链表等各种操作。对链表的操作无需关注细节,可直接调用。代码易于理解,并且如果新增功能直接调用函数即可,无需重写代码。
  menu模块并不需要知道LinkTable内方法的具体实现过程,只需要关注自身的具体实现即可,需要就调用LinkTable模块。

三、可重用接口

  模块化的设计,使每个模块都各司其职,分工明确。但与此同时,各个模块也提供了跨模块调用的方法。因为在一个项目代码中,各子功能仍有一定的耦合度与内聚度,不存在完全独立的模块。

  接口是模块间共同遵守的一种协议规范,定义了软件模块对系统的其他部分提供了怎样的服务,以及系统的其他部分如何访问所提供的服务。

 

四、线程安全

1.线程的概念

  线程是能够进行调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一个进程可以有很多线程,每条线程并行执行不同的任务。

2.线程安全的概念

  线程安全指的是多线程的安全。如果一段程序可以保证被多线程访问后仍能保持正确性,那么程序就是线程安全的。一般来说,线程安全注重的是多线程开发中的共享数据的安全。

3. Linktable模块的线程安全分析

 1 int DelLinkTableNode(tLinkTable *pLinkTable,tLinkTableNode * pNode)
 2 {
 3     if(pLinkTable == NULL || pNode == NULL)
 4     {
 5         return FAILURE;
 6     }
 7     pthread_mutex_lock(&(pLinkTable->mutex));
 8     if(pLinkTable->pHead == pNode)
 9     {
10         pLinkTable->pHead = pLinkTable->pHead->pNext;
11         pLinkTable->SumOfNode -= 1 ;
12         if(pLinkTable->SumOfNode == 0)
13         {
14             pLinkTable->pTail = NULL;    
15         }
16         pthread_mutex_unlock(&(pLinkTable->mutex));
17         return SUCCESS;
18     }
19     tLinkTableNode * pTempNode = pLinkTable->pHead;
20     while(pTempNode != NULL)
21     {    
22         if(pTempNode->pNext == pNode)
23         {
24             pTempNode->pNext = pTempNode->pNext->pNext;
25             pLinkTable->SumOfNode -= 1 ;
26             if(pLinkTable->SumOfNode == 0)
27             {
28                 pLinkTable->pTail = NULL;    
29             }
30             pthread_mutex_unlock(&(pLinkTable->mutex));
31             return SUCCESS;                    
32         }
33         pTempNode = pTempNode->pNext;
34     }
35     pthread_mutex_unlock(&(pLinkTable->mutex));
36     return FAILURE;        
37 }
pthread_mutex_unlock(&(pLinkTable->mutex))的使用就是为了保护线程的安全使用
五、总结
  通过孟老师课堂的讲解,结合menu项目代码分析各个知识点的具体实现,使我对软件工程有了更深的理解。在以后的学习中希望有更多的机会可以深入接触更多的软件工程开发方法和技巧,不断进步。
posted @ 2020-11-09 18:23  runforrestrun  阅读(229)  评论(0)    收藏  举报