软件开发的一个案例:学生信息管理系统

前言

学生信息管理系统——相信我们大家都是比较熟悉的了,作为一个初入计算机专业的学生,这估计是我们在课程设计中都做过的一个小项目。不过你我那时可能一样,因为经验不足和图于玩乐,开发过程中水了不少地方,哈哈一开;近日临近学期末 ,因为一些原因,需要来重新做一下它,鉴于以前的不足,所以本次开发参照着软件工程开发流程走,算是对软件开发流程再一次巩固。


项目需求

首先第一个考虑的便是项目需求,对于咱学生来讲,项目可行性就不用研究了,这肯定是可行的,砸门就经拿需求干就是了。废话不多讲,先能得到大致功能需求模块,例如针对本项目经过一番分析可以得到如下需求模块图:

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库

最后贴上程序截图:

  1. 主界面图
  2. 管理员登录
  3. 学生登录
  4. 成绩查询

猜你喜欢

转载自www.cnblogs.com/tp-16b/p/10283637.html