模块化编程-以图书管理系统为例

本文探讨了如何通过模块化编程思想改进代码结构,以实现更清晰的职责划分。以图书管理系统为例,详细解释了界面显示代码、数据处理代码和交互类代码在添加图书功能中的作用。通过将不同类型的代码封装到独立函数,降低耦合度,提高代码复用性,进而提升了整体系统的可维护性和扩展性。
摘要由CSDN通过智能技术生成

为了实现一个完整的业务功能,一般来说你的代码会包含至少三种类型的代码:

  1. 界面显示代码:用来显示界面、输出数据。
  2. 数据处理代码:一般来说只对数据进行处理。比如,对存在数组或链表中的数据进行增删改查。
  3. 交互类代码:处理用户的输入与输出。比如,根据用户输入调用"数据处理代码"处理数据,调用"界面显示代码"显示数据或显示界面,从而实现一个完整的业务功能。

比如,对于图书管理系统的功能“添加图书”,有的同学这样编写。

AddBook()
{
     // 显示菜单的代码-类型1
     // 提示用户输入、从控制台读入用户输入数据-类型3
     // 根据输入进行数据处理的代码。比如在链表中添加某个节点-类型2
     // 将输出输出或者显示菜单-类型3
     // 为了编写方便可能还需大量地使用了全局变量。比如,为了往图书列表中添加数据,需访问全局变量booklist。
}

这样编写,固然易于实现,然而不符合模块化编程思想。代码中,数据处理代码、界面显示代码、交互类代码耦合,难以复用。

模块化编程

应将不同类型的代码封装到独立地函数中,方便复用。对于"添加图书"功能可以写如下几个函数:

  1. void AddBook(BookList booklist) //进入添加图书功能
  2. int AddBook(BookList booklist, Book book)//只包含在bookList中添加book的代码,不涉及任何界面与输入输出代码。返回状态码:-2,添加失败,因为已经存在;-1, 添加失败,因为分配内存不成功;其他正整数n,添加成功,返回值为添加的位置
    说明:void AddBook(BookList booklist)使用一个booklist作为输入参数,就避免了使用全局变量。

图书管理系统伪代码

1. AddBook(BookList booklist)伪代码

AddBook(BookList booklist)
{
  1. ListAllBooks(booklist); // 格式化显示所有图书的代码-界面显示代码
  2. 处理用户需要添加的图书信息,生成了book结构体。 // 交互类代码
  3. int status = AddBook(booklist, book); // 数据处理代码
  4. 根据status进行相应的处理的代码,可能包含:// 交互类代码
    - 提示添加出错,并显示出出错原因
    - 提示添加成功与添加位置->DispBook(book)。注意DispBook为一个专门格式化显示Book的函数-界面显示代码。
  5. 根据用户输入选择是继续添加还是返回。 //交互类代码
}

从这个例子中可以看到,交互类代码用来协调控制"数据处理代码"和"界面显示代码"
在这里,交互类代码起到一个控制器的作用,处理输入->调用数据处理代码->根据执行结果选择合适的界面显示代码。
通过交互类代码的穿针引线,最终完成了"添加图书"这个完整功能。

2. main函数伪代码

main()
{
    booklist = InitBookList() // 初始化图书列表。可能从文件系统读取图书数据,也可能直接通过代码生成数据。
    while(true)
    {
        MainMenu() // 图书管理系统主菜单-界面显示代码。
        choice = input(); // 提示用户输入选择-交互类代码
        switch (choice) {
	    case 1: // 浏览图书列表
	        ListAllBooks(booklist);
	        break;
	    case 2: // 添加图书
	        AddBook(booklist)
                break;
            其他case...:
                ....
                break;
	    default:
                // 处理输入错误的情况
		break;
	}
    }  
}

这样的编写就比较符合模块化编程的思想:

  1. 每个函数只做一件事情。
  2. 有效地控制了函数的规模(行数)。
  3. 避免了对全局变量的使用。
  4. 方便了代码的复用。比如,这里通过ListAllBook、AddBook、DispBook、MainMenu这几个函数实现了代码复用。

其他编程规范相关资料

C语言程序设计课程设计自查表格

这是一个比较复杂的数据库 包含图书管理 借书还书 学生管理 老师管理 和数据连接的相关应用 代码有详细的解释 压缩包里面也有 数据库的文件 代码里设置的数据库 用户是 sa 密码是 123456 请使用的时候做相关的修改 下面给出 一部分的代码 请继续关注本资源的发布 会后面有很多实用的代码上传 using System.Windows.Forms; namespace LibraryMis { public class DatabaseAccess { /* 声明成员变量,这样这个类中的所有方法就可是使用这些变量了 */ private SqlConnection myConnection; private SqlCommand myCommand; private SqlDataAdapter myDataAdapter; private DataSet mySet = new DataSet(); /* 写该类的构造方法,该方法名要跟类名相同,无返回值 * 当new这个类时就会执行这个构造方法 */ public DatabaseAccess() { /* 获得保存连接字符串的文件名及路径 */ //获得应用程序路径 string exePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; //根据路径和文件名构建FileInfo对象 string fileName = exePath + "connectionString.txt"; //建立FileInfo对象 FileInfo f = new FileInfo(fileName); //判断该文件是否存在 if (f.Exists)//文件存在 { //获得文件内容即存在文件中的连接字符串 //打开文件,获得读文件的数据流对象 StreamReader sr = f.OpenText(); //读文件到变量中 string connectionString = sr.ReadToEnd(); //关闭流 sr.Close(); //由读出的连接字符串创建Connection对象 myConnection = new SqlConnection(connectionString); //由Connection对象创建Command对象 myCommand = myConnection.CreateCommand(); //创建DataAdapter对象 myDataAdapter = new SqlDataAdapter(); myDataAdapter.SelectCommand = myCommand; //创建CommandBuilder对象 SqlCommandBuilder cb = new SqlCommandBuilder(myDataAdapter); //尝试是否能够打开连接 try { myConnection.Open(); } catch (Exception ex) //打开连接出错,可能是连接字符串有问题,这里调用数据库访问设置窗体来重新设置服务器名和数据库名 { MessageBox.Show("连接不到数据库LibraryMis,请在“数据库访问设置窗体中对数据库访问进行正确的设置”" + ",取消登录后重新启动图书馆管理系统!","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning ); //创建 数据库访问设置窗体,并显示 FormSetDatabase fmsd = new FormSetDatabase(); fmsd.ShowDialog(); } finally { try { myConnection.Close(); } catch (Exception ex) { } } return; } else //文件不存在 { //设置默认的连接字符串 string connectionString = "server=.;database=LibraryMis;uid=sa;pwd=123456"; //把这个字符串写入文件 StreamWriter sw = new StreamWriter(fileName); sw.Write(connectionString); sw.Close(); MessageBox.Show("文件" + fileName + "不存在,已创建该文件,请重新启动图书馆管理系统","警告",MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } /*创建查询的方法,返回数据集对象DataSet,参数SelectString表示查询的Sql语句,TableName表示要查询的表名*/ public DataSet FillDataSet(string SelectString, string TableName) { myDataAdapter.SelectCommand.CommandText = SelectString;//设置查询的Sql语句 myDataAdapter.Fill(mySet,TableName); return mySet; } /*执行插入,更新,修改的操作,参数CommandString表示Sql语句*/ public void ExeCommand(string CommandString) { myCommand.CommandText = CommandString; myConnection.Open(); try { myCommand.ExecuteNonQuery(); } catch (Exception ex) { MessageBox.Show(ex.ToString(),"警告",MessageBoxButtons.OK,MessageBoxIcon.Warning); } finally { myConnection.Close(); } } /*执行存储过程的方法,参数为Command对象*/ public void ExeStoreProcedure(SqlCommand command) { command.Connection = myConnection; myCommand = command; myConnection.Open(); try { myCommand.ExecuteNonQuery(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } finally { myConnection.Close(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值