资讯动态

软件工程课程设计:选课系统从需求分析到验收的完整技术路线

发布时间:2026/10/23 8:02:19 来源:尧图企业网站定制
简介《软件工程课程设计指导书》是一份面向计算机科学与技术专业学生的软件工程实践入门指南围绕一门10学时的上机课程设计展开帮助初学者运用软件工程思想与面向对象方法从零完成一个选课系统的开发。资源包仅包含1个doc文档大小539KB属于纯文本指导材料适合学生在课程设计前通读。内容从实验目的、面向专业、先修课程到实验环境均有说明并以选课系统为例给出数据字段、功能要求和设计规范。报告部分明确了需求分析、软件设计、软件测试、源代码与个人总结的写作要点附录还整理了通过ODBC建立数据库连接及C Builder 6.0的基本操作步骤对缺乏实践经验的读者尤为实用。全文已服务97位学习者可作为软件工程课程设计的高效参考和完整操作指引。1. 软件工程课程设计指导书选课系统要从需求分析一路做到验收每年做软件工程课程设计最常见的翻车方式不是代码写不出来而是拿到“选课系统”这类题目就直接开窗体、拖控件等到交报告的时候才发现需求分析、用例图、序列图、状态图全都没画测试数据也凑不够二十条最后只能熬夜补文档。这套课程设计的核心矛盾在于上机只有 10 学时但交付物却要求一个能运行的面向对象小型系统加一份完整报告没有一套从需求到验收的固定打法很容易顾此失彼。这份指导书的价值就是把“用 C Builder 6.0 Access 2000 开发选课系统”这件事拆成一条可执行的技术路线适合计算机科学与技术专业的同学照着做也适合指导老师当作检查学生进度的依据。我接下来的方案完全围绕“先立需求、再定设计、最后能落地验收”这条主线展开。2. 需求分析与总体架构先画用例图和序列图再谈代码实现2.1 需求分析阶段到底要交付什么很多同学拿到题目就急着建工程实际上需求分析阶段要交付的内容并不复杂但必须完整。指导书里点名的字段至少包括学生姓名、学号、登录密码、性别、出生年月、籍贯、地址、学生电话、家庭地址、教师号、教师姓名、教研室、职称、教师电话、课名、课号、学分、先行课号、课时、开课教室、人数限制、选课人数、考试成绩、平时成绩、总评成绩。这些字段不是随便列的它们决定了后续数据库表怎么拆分。把字段归归类就会发现天然分成三张表学生表、教师表、课程表。选课关系呢可以用一张选课记录表来表达选课记录表里关联学生号和课号另外再带考试成绩、平时成绩、总评成绩。这个拆分方式符合第三范式的思路也是指导书要求“采用面向对象方法”但数据层仍然要关系化的原因。我一般会建议学生先别碰代码用一页纸画出系统的用例图。选课系统的参与者其实就两类学生和管理员也可以叫教师端。学生能做的操作是登录、查询开课情况、查询选课情况、查询成绩、选课、退课管理员能做的是维护课程信息、维护学生信息、录入成绩。用例图画完数据流就清楚了一半。序列图是这个阶段的第二个关键产物。我通常要求学生至少画两个序列图一个是学生选课的完整流程——登录系统、验证身份、查询开课列表、选择课程、系统检查人数限制、写入选课记录、返回结果另一个是学生查询成绩的流程——登录、选择查询成绩、系统从选课记录表读取成绩字段、展示结果。序列图画完后面写代码时函数调用顺序基本就定死了。2.2 总体架构和三层职责划分选课系统的架构不需要做得花哨三层足矣界面层负责窗体展示和用户交互业务层负责选课、退课、成绩计算这些规则数据层负责通过 ODBC 访问 Access 数据库。C Builder 6.0 里界面层就是 Form 上的组件业务层可以封装成独立的类比如选课管理器类、登录验证类数据层用 ADOConnection 或者 BDE 别名来访问 Access 文件。架构上最容易犯的错误是把 SQL 语句直接写在按钮的 Click 事件里。一个窗体里塞十几个数据感知组件和 SQL 语句系统确实能跑但测试的时候就会发现耦合太紧换一个数据库结构就要重写一片代码更真实的问题是状态图根本没法画——业务规则散落在界面代码里对象的状态无法追踪。通常的做法是给系统拆出四个核心类用户验证类负责登录验证和密码处理、课程查询类封装开课情况和选课情况的查询逻辑、选课处理类负责选课、退课、人数校验、成绩处理类负责成绩的读取和总评成绩计算。每个类对应一组独立的函数界面层只调用这些类的公开方法不直接操作数据库。2.3 数据库表设计和 Access 建模Access 2000 里建表我建议按下面这个结构来设计字段名可以自己改但语义要一致。表名关键字段说明Student学号、姓名、密码、性别、出生年月、籍贯、地址、电话主键是学号Teacher教师号、教师姓名、教研室、职称、性别、电话主键是教师号Course课号、课名、学分、先行课号、课时、开课教室、人数限制、选课人数、教师号主键是课号教师号外键关联 TeacherEnrollment选课记录ID、学号、课号、考试成绩、平时成绩、总评成绩学号课号联合唯一Access 里建表有个坑就是默认的主键类型是“自动编号”但学号这种业务字段必须用文本类型而且在建立表关系时要把“实施参照完整性”勾上。我当时帮同学排查数据不一致的问题最后发现就是建表时没建立表间关系学生退了一门课选课记录删了但课程的选课人数字段没跟着减这种低级错误在验收演示时特别容易暴露。3. 关键技术路线C Builder 6.0 Access 2000 ODBC 的取舍与连接3.1 为什么是 C Builder 6.0 而不是其他工具选课系统之所以默认用 C Builder 6.0不是因为它是选课系统的最佳工具而是因为指导书的上机环境就是这么定的Windows 操作系统、C Builder 6.0、Access 2000。C Builder 6.0 的 VCL 组件库让界面开发效率很高TADOQuery、TDataSource、TDBGrid 这几个组件配合使用几分钟就能搭出一个数据展示窗体这对 10 学时的上机时间来说非常关键。但 C Builder 6.0 有个明显的短板它的 BDE 和 ODBC 配置在 Windows 新版本上经常出问题而且 IDE 崩溃后恢复工程比较麻烦。所以我在做技术路线验证时建议学生先在小范围内跑通“窗体 数据库连接 单表查询”再扩展成完整功能不要一上来就搭十几个窗体。另外要强调的是面向对象方法在这个项目里不是让你把所有逻辑都做成类继承树。课程设计考核的重点是你能不能按软件工程的过程走下来——需求有没有分析、设计有没有建模、测试有没有设计数据。技术选型反而是次要的够用就行。3.2 ODBC 数据源配置与 BDE 别名设置这份指导书附录给了非常详细的 ODBC 配置步骤实际执行时核心就三步Access 里建好数据库文件、控制面板里配置 ODBC 数据源、BDE Administrator 里把别名指到该数据源。下面这个配置流程是从指导书附录压缩出来的用 Access 2000 建立选课.mdb建好表结构并录入少量测试数据。打开控制面板里的 ODBC 数据源管理器添加一个“Microsoft Access Driver (*.mdb)”的用户数据源数据源名填“选课数据源”数据库选择刚才的 mdb 文件。打开 BDE Administrator新建一个 Database 别名驱动选 Microsoft Access Driver然后将 ODBC DSN 指向刚才创建的数据源名称。右键别名 Apply再右键 Open输入数据库登录信息后如果字体变黑说明连接成功。提示BDE 和 ODBC 的配置在部分 Windows 环境下会互相“抢”配置。如果 Open 时提示驱动不认识先检查系统是否缺少 Access 驱动再检查数据源名是否完全一致包括空格和大小写。3.3 ADOConnection 连接数据库的两种方式C Builder 6.0 里连接数据库有两种思路一种是通过 BDE 别名在 ADOConnection 的连接字符串里写 Provider 和 Data Source另一种是直接用 ODBC 数据源名连接。给学生的建议是上机环境如果统一配置好了 BDE用指导书里的方式走一遍如果自己电脑上装的环境有问题可以直接用 ODBC 数据源名少一层 BDE 反而更稳。我一般建议用下面这种连接字符串格式写在 ADOConnection 的 ConnectionString 里这样程序启动时会自动读配置不用每次上机都重新配// ADOConnection1-ConnectionString 示例 ProviderMSDASQL.1;Persist Security InfoFalse;Data Source选课数据源设计说明用 MSDASQL 提供程序走 ODBC 桥接Data Source 必须和系统里配置的 ODBC 数据源名称完全一致。Persist Security Info 设为 False表示不把密码保存在连接字符串里。这样写的好处是代码里不暴露数据库路径换一台机器只要重新配置同名 ODBC 数据源就能直接跑。4. 模块设计与核心实现登录、查询、选课、退课与成绩管理4.1 登录模块与权限校验登录模块是整个系统的入口也是最容易出低级问题的地方。功能很简单用户在登录窗体输入学号和密码系统去 Student 表里校验匹配成功则进入主窗体失败则提示错误信息。C Builder 里可以这样写核心逻辑// 登录验证核心函数 bool LoginCheck(AnsiString userId, AnsiString password) { // 通过 TADOQuery 查询学生表 ADOQuery1-SQL-Clear(); ADOQuery1-SQL-Add(SELECT COUNT(*) AS cnt FROM Student WHERE 学号:uid AND 密码:pwd); ADOQuery1-Parameters-ParamByName(uid)-Value userId; ADOQuery1-Parameters-ParamByName(pwd)-Value password; ADOQuery1-Open(); // 查询结果计数大于 0 说明匹配成功 int count ADOQuery1-FieldByName(cnt)-AsInteger; return count 0; }这段代码用了参数化查询而不是字符串拼接核心考虑是防止输入引号或特殊字符时破坏 SQL 语句。另一个细节是密码字段在 Access 里不要用加密课程设计阶段明文存储可接受但报告中要提及这是简化处理并说明真实系统的密码应该做哈希。4.2 查询模块开课情况、选课情况和成绩查询查询开课情况是学生使用频率最高的功能。界面可以用一个 TDBGrid 显示课程列表数据源来自 Course 表关联 Teacher 表的查询语句。这里要特别注意查询语句必须带 WHERE 条件比如按课名模糊查询、按开课教室筛选否则学生要在一大张表里翻数据体验很差。-- 查询开课情况含任课教师信息 SELECT c.课号, c.课名, c.学分, c.课时, c.开课教室, c.人数限制, c.选课人数, t.教师姓名 FROM Course c LEFT JOIN Teacher t ON c.教师号 t.教师号 WHERE c.课名 LIKE % :kw %这里用了 LEFT JOIN 是为了避免教师信息缺失的课程显示不出来。教职工表里录入数据时如果漏填教师号用 INNER JOIN 会直接把课程记录过滤掉用 LEFT JOIN 至少还能看到课程本身对调试阶段更友好。查询选课情况和查询成绩的逻辑类似区别在于查询选课情况要用学号关联 Enrollment 和 Course 两张表查询成绩则直接读 Enrollment 表的成绩字段。4.3 选课与退课的并发与限制校验选课模块的核心规则是同一学生不能重复选同一门课课程选课人数不能超过人数限制。这两条规则必须在业务层判断不能只靠数据库约束。C Builder 里选课操作按事务方式处理最稳妥// 选课处理逻辑 void ProcessEnroll(AnsiString studentId, AnsiString courseId) { // 第一步检查课程是否已满 ADOQuery1-SQL-Clear(); ADOQuery1-SQL-Add(SELECT 人数限制, 选课人数 FROM Course WHERE 课号:cid); ADOQuery1-Parameters-ParamByName(cid)-Value courseId; ADOQuery1-Open(); int limit ADOQuery1-FieldByName(人数限制)-AsInteger; int current ADOQuery1-FieldByName(选课人数)-AsInteger; if (current limit) { ShowMessage(该课程已选满无法选课); return; } // 第二步检查是否重复选课 ADOQuery1-SQL-Clear(); ADOQuery1-SQL-Add(SELECT COUNT(*) AS cnt FROM Enrollment WHERE 学号:sid AND 课号:cid); ADOQuery1-Parameters-ParamByName(sid)-Value studentId; ADOQuery1-Parameters-ParamByName(cid)-Value courseId; ADOQuery1-Open(); if (ADOQuery1-FieldByName(cnt)-AsInteger 0) { ShowMessage(您已选过该课程); return; } // 第三步写入选课记录并更新选课人数 ADOConnection1-BeginTrans(); try { ADOQuery1-SQL-Clear(); ADOQuery1-SQL-Add(INSERT INTO Enrollment(学号, 课号) VALUES(:sid, :cid)); ADOQuery1-Parameters-ParamByName(sid)-Value studentId; ADOQuery1-Parameters-ParamByName(cid)-Value courseId; ADOQuery1-ExecSQL(); ADOQuery1-SQL-Clear(); ADOQuery1-SQL-Add(UPDATE Course SET 选课人数 选课人数 1 WHERE 课号:cid); ADOQuery1-Parameters-ParamByName(cid)-Value courseId; ADOQuery1-ExecSQL(); ADOConnection1-CommitTrans(); } catch (...) { ADOConnection1-RollbackTrans(); ShowMessage(选课失败已回滚); } }这里的核心设计思路是事务保护先检查再写入写入时同时更新选课记录和课程人数两步操作放在同一个事务里任何一步失败都回滚。退课逻辑是选课的镜像操作删除 Enrollment 记录后把 Course 表选课人数减一同样放在事务里。最容易被忽略的是并发场景——两个学生在同一时间选最后一门课单机模式很难复现但报告里要提到这个问题说明事务是解决方案。4.4 成绩管理与总评计算成绩管理模块面向教师端录入平时成绩和考试成绩系统自动计算总评。总评成绩的计算规则按实际情况设计常见的是平时成绩占 30%、考试成绩占 70%这个比例在报告的需求分析里就要写明代码里用常量定义方便后续修改。// 计算总评成绩 float CalculateFinalScore(float usualScore, float examScore) { const float USUAL_WEIGHT 0.3f; // 平时成绩权重 const float EXAM_WEIGHT 0.7f; // 考试成绩权重 return usualScore * USUAL_WEIGHT examScore * EXAM_WEIGHT; }代码里的权重参数为什么用常量而非直接写在表达式里因为课程设计的成绩计算规则有可能在验收前被老师临时调整如果权重散落在代码各处改起来容易漏。成绩模块的界面通常是一个 TDBGrid 直接绑定 Enrollment 表教师在表格里输入成绩后点击“保存”按钮统一写库这样比一条条更新更高效也方便批量操作。5. 常见问题与避坑指南BDE/ODBC 配置、乱码与数据不一致5.1 BDE 连接字体变红或黑、连接失败现象在 BDE Administrator 里右键 Open 后别名项一直显示红色或者弹出 Database Login 对话框后输入任何密码都提示失败。原因最常见的是 ODBC 数据源名称和 BDE 别名指向的 DSN 不一致多了一个空格或大小写不同其次是系统缺少 Microsoft Access Driver 驱动特别是 64 位系统默认装的是 64 位驱动而 32 位的 C Builder 6.0 需要 32 位驱动。解决打开 ODBC 数据源管理器确认数据源名称是纯文本且无特殊字符再回到 BDE Administrator 双击别名检查 ODBC DSN 下拉框里选中的是不是同一个名称。如果提示驱动问题重新安装 Microsoft Access Database Engine并确保把 32 位版本装到了正确路径。5.2 界面显示中文乱码现象TDBGrid 里查询结果显示中文变成问号或者乱码但 Access 里数据本身是正常的。原因C Builder 6.0 的组件默认字符集是 ANSI而 Access 2000 的数据库可能是按系统区域设置存储的两者在字符编码上不一致还有可能是 ODBC 连接时没有正确指定字符集。解决最简单的方式是在 ADOConnection 的连接字符串里面加上“Character Set”相关参数或者在每个 TADOQuery 的 SQL 执行前设置 Session 的字符集。实际操作中我一般先检查 Access 表字段的文本类型是不是文本如果字段类型是备注或者 OLE 对象读取时也容易出现显示问题。避免踩坑的办法是建表时所有中文文本字段统一用“文本”类型长度给够不要用备注。5.3 选课人数和选课记录数量对不上现象Course 表里选课人数是 10但 Enrollment 表里关联该课程的记录只有 8 条或者反过来记录比人数多。原因选课或退课操作没有做成事务插入选课记录成功后更新课程人数的 SQL 执行失败导致两边数据不一致或者退课时只删了 Enrollment 记录忘了更新人数。解决检查所有选课和退课的代码路径必须按事务方式执行——先写 Enrollment 再更新 Course 人数任何一步失败就回滚。另外可以在 Access 层面建立一个简单的检查查询定期比对两张表的数据这个操作可以在报告测试部分展示为数据完整性验证用例。从那以后我每次给学生检查选课系统第一件事就是数数选课人数和选课记录是否对得上这个习惯救过不少翻车的演示。5.4 工程文件换电脑后打不开现象在自己电脑上开发正常的工程拷贝到另一个同学电脑上打开提示找不到 BDE 别名或数据库文件路径无效。原因C Builder 6.0 的工程文件里保存了绝对路径数据库连接字符串里引用的数据源是配置在某台机器上的 ODBC 名称换机器后这个名称不存在。解决把数据库文件和工程放在同一级目录下连接字符串里使用相对路径或者通过在程序启动时动态配置数据源名称来规避绝对路径依赖。验收前我要求学生在另一台机器上完整走一遍部署流程——配置 ODBC、设置 BDE 别名、启动程序。能复现就说明部署步骤是完整的答辩被问起时也更有底气。5.5 报告里的图与代码对不上现象报告里的序列图画的是“学生选课后自动更新课程人数”但代码里选课功能根本没有更新人数。原因先写代码后补文档画图时凭想象补流程导致图与实现脱节。这是评审老师最反感的硬伤。解决报告里每一张用例图、序列图、状态图都要跟代码的调用链一一对应。画完图后拿着图走一遍代码图上有一步而代码里没有的要么补代码要么改图。我见过不少系统其实功能齐全就是图对不上被老师认定为“文档抄袭”这个坑提前排查比事后解释划算得多。6. 测试设计与答辩验收20 条测试序列和演示技巧测试数据的要求很明确至少要有 20 个不同的对象测试序列。这里“对象”指的是业务操作实例比如一个学生完成“登录→查询课程→选课→退课→再次选课→查询成绩”算一个测试序列。我建议按功能模块来设计测试矩阵而不是随机点一点界面。编号测试序列预期结果01正确密码登录进入主窗体02错误密码登录提示密码错误03查询全部开课课程返回课程列表04按课程名模糊查询返回匹配课程05选择未满课程选课成功06选择人数已满课程提示已满07重复选择同一课程提示已选过08退掉已选课程选课记录删除09退课后重新选同一门课可以选课成功10查询选课情况显示已选课程11录入平时成绩保存成功12录入考试成绩保存成功13计算总评成绩按权重计算正确14课程人数超限后选课被拒绝15未登录直接访问主窗体被拦截16选课后查询课程人数人数加 117退课后查询课程人数人数减 118修改密码后重新登录新密码生效19查询已退课程成绩无记录20多条件组合查询结果准确每条测试序列都要记录输入数据、操作步骤、实际输出和测试结果这个表格直接放进报告测试部分比写“系统测试通过”这种一句话有说服力得多。测试时注意覆盖正常流和异常流——异常流才更能体现软件工程素养比如选满课程、重复选课、密码错误这些反向用例评审老师通常会盯着这些场景提问。答辩演示的节奏也很重要我带的项目组通常按这条线走先演示登录再查一门具体的课程现场选课然后查选课情况确认再退课最后查成绩。整个过程控制在三分钟以内每一步都干净利落。不要漫无目的地在界面上乱点更不要在演示开始前才重新编译工程——答辩前最后一次完整编译和运行测试必须提前完成现场大概率没有时间修 bug。报告装订顺序按指导书来选题、报告个人信息、课程设计目的、设计要求、设计内容需求分析、软件设计、软件测试、源代码、总结。需求分析部分一定要有你的用例图和序列图软件设计部分要有对象模型和至少一个重要对象的状态图源代码部分只放手动编写的代码自动生成的部分不要塞进去凑页数。总结里系统评价和自我心得分开写自我心得不要写空话“学会了事务处理”“理解了状态图的作用”这种具体收获比“学到了很多”有价值得多。希望这份完整解决方案能帮到你更希望你拿着这套方案走一遍流程之后能感受到软件工程不是一堆文档的堆砌而是让代码从一开始就少犯错的工程习惯。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑