软件开发的一个案例:学生信息管理系统
前言
学生信息管理系统——相信我们大家都是比较熟悉的了,作为一个初入计算机专业的学生,这估计是我们在课程设计中都做过的一个小项目。不过你我那时可能一样,因为经验不足和图于玩乐,开发过程中水了不少地方,哈哈一开;近日临近学期末 ,因为一些原因,需要来重新做一下它,鉴于以前的不足,所以本次开发参照着软件工程开发流程走,算是对软件开发流程再一次巩固。
项目需求
首先第一个考虑的便是项目需求,对于咱学生来讲,项目可行性就不用研究了,这肯定是可行的,砸门就经拿需求干就是了。废话不多讲,先能得到大致功能需求模块,例如针对本项目经过一番分析可以得到如下需求模块图:
1 考虑学生登录,可以将其细分如下一些需求:
2 管理员登录
对于管理员登录,它管理的东西就比较多了。就其中的课程管理,大致对应着的其实就是增、删、查、改课程
对于教室管理、学生管理、班级管理 需求是类似的
分析一下学生选课管理、学生成绩管理,也不难得到下面的功能需求图:
一个简单E-R图帮助了解需求
系统设计
前面需求阶段都还比较顺风顺水, 到设计阶段就遇到了阻碍。参照前面的E-R图,比较容易得到这么几个类:
Student类 Teacher类 Course类 Admin类 Grade班级类
难点在于类之间的交互
废话不多讲,以学生选课为例,下面是我设计<1>Student类和Course类实现交互:
Course类
#include "common.h"
struct Course
{
string course_id_; //课程id
string course_name_;//课程名
int times_; //学时
int credit_; //学分
Course(const string& ci="C00", const string& cn="", int times=0, int c=0, int s=0)
:course_id_( ci),course_name_( cn),times_(times),credit_(c) { }
bool operator<(const Course& rhs) const{
if(course_id_ < rhs.course_id_) return true;
else return false;
}
};
//管理课程类
class ManageCourse
{
typedef set<Course>::iterator Ite;
private:
set<Course> contain_; //存储课程set容器
public:
int addCourse(const string& , const string& , int, int) ;
int changeCourse(const string&) ;
int eraseCourse(const string&) ;
Ite findCourse(const string& c_id) {return contain_.find(Course(c_id));}
void showCourse(); //显示系统中所有课程信息
};
Student类
class Student
{
typedef map<Course, int>::iterator Ite;
private:
string usn_;
string name_;
string profession_; //专业
string email_;
string birth_; //出生日期
string sex_; //性别
string password_;
ManageCourse* pMC_; //ManageCourse进行交互,从系统选得课程
map<Course, int> con_score_;//存储课程及其对应分数的map容器
public:
Student(ManageCourse* pmc, ....): .....{} //简写了
//个人信息操作
void showProfile(); //显示学生个人信息
int changePWD();
//选课管理
void manageCourse(const string& admin_id);
int addCourse(const string& c_id) ; //添加课程至con_score_容器
int cancleCourse(const string& c_id) ;
void showCourseScore() ; //显示学生所有课程与分数
...
};
可以看出Student类中有一个操纵Course的句柄,由它来负责和ManageCourse课程类交互,进而实现从系统选课的操作;再者在Student类中存有一个存放课程和对应分数的map容器,这样利用pMC_句柄在系统找到的课程便可以放入map容器进行管理
<2> Admin类与Course类进行交互
同上,Admin类需要实现对系统的课程进行管理就十分简单了,只需要在类中添加ManageCourse* 类型数据成员,用作操作管理课程的句柄。
class Admin
{
private:
int admin_id_;
string admin_name_;
string admin_pass_;
ManageCourse* pMC_; //管理课程句柄
public :
Admin(ManageCourse* pMC, ...)::...,pMC_(pMC) { }
~Admin( ) { ...}
ManageStudent* getStuHandle( ) { return pMS_;}
//manage course member function
void manageCourse();
//handle student choose course
void handleChooseCourse( );
void addCourseForStu();
void cancleCourseForStu();
};
不过这里有一个十分值得注意的问题:pMC_属性必须和Student类中pMC_属性指向同一个ManageCourse对象。因为它们需要统一进行交互
也就是说pMC_属性是在构造admin 对象时,外面用参数传进来。
对于教师管理、班级管理、学生管理可以基于同样的思路进行处理。只需要在Admin类中添加相应的句柄。
数据保存
所有数据保存在mysql中。在程序启动时从数据库中加载到维护的数据结构中,所有操作完成后再将数据保存到mysql中。
之所以如此,可以减少程序与mysql交互的次数,提高执行的效率
编码实现
至此,已有大体的思路,可以开始编码实现。代码已上传github,若您感兴趣可以参考https://github.com/tp16b/project/tree/master/manageSys/src
注意事项:
- 执行环境是Linux,若执行代码请clone整个工程
- 程序用到mysql保存,执行前请确保安装好mysql
- c++连接mysql需要用到libmysqlclient-dev库
最后贴上程序截图:
- 主界面图
- 管理员登录
- 学生登录
- 成绩查询
本文来自博客园,作者:tp_16b,转载请注明原文链接:https://www.cnblogs.com/tp-16b/p/10283637.html