- 本项目旨在设计一个简化的企业管理信息系统(Enterprise Management Information System,EMIS)项目
2. 需求分析
2.1. 总体需求
企业管理信息系统主要用于实现对企业基本信息的管理。具体包括对企业部门的管理、对企业员工的管理,以及对管理信息系统本身的管理。
其中,对管理信息系统本身的管理主要是指对管理员的管理,这方面的需求可被归纳为管理需求,而对企业部门和员工的管理则被归纳为业务管理。2.2. 管理需求
管理需求主要包括:
- 增加管理员:根据屏幕提示依次输入管理员的用户名和密码,系统自动为其分配ID号,并向用户提供反馈信息。
- 删除管理员:根据屏幕提示输入欲删除管理员的ID号,系统将该管理员删除,并向用户提供反馈信息。
- 列出所有管理员:系统以列表形式显示所有管理员的ID号、用户名和密码。
2.3. 业务需求
业务需求主要包括:
- 部门管理包括:
- 增加部门:根据屏幕提示输入部门名称,系统自动为其分配ID号,并向用户提供反馈信息。
- 删除部门:根据屏幕提示输入欲删除部门的ID号,系统将该部门删除,并向用户提供反馈信息。
- 生成部门列表:系统以列表形式显示所有部门的ID号、部门名称和员工人数。
- 员工管理则包括:
- 增加员工:根据屏幕提示依次输入员工的姓名、性别、年龄,以及所属部门的ID号等信息,系统自动为其分配ID号,并向用户提供反馈信息。
- 删除员工:根据屏幕提示输入欲删除员工的ID号,系统将该员工删除,并向用户提供反馈信息。
- 修改员工信息:根据屏幕提示选择要修改的员工信息然后并输入,系统更新与该员工有关的信息数据,并向用户提供反馈信息。
- 生成员工列表:根据屏幕提示输入部门的ID号,系统以列表形式显示该部门所有员工的ID号、姓名、性别和年龄。
- 列出所有员工:系统以列表形式显示所有员工的部门、ID号、姓名、性别和年龄。
3. 概要设计
3.1. 总体架构
根据前述需求分析,本案在逻辑上可被划分为管理子系统和业务子系统两大模块,分别用于实现对管理员的管理和对部门及员工的管理功能。此外还需提供必要的数据存储策略,以实现对所有数据的持久化。系统总体架构如图所示:
管理子系统:实现对管理员的管理功能。具体包括增加管理员、删除管理员、列出所有管理员。
用户界面:显示主菜单、接受用户输入、向用户显示提示信息、处理结果和必要的反馈。
业务逻辑:具体实现主菜单的各个功能项,以逻辑对象为载体,在用户界面和数据访问之间传递有关管理员的信息数据。
数据访问:实现逻辑对象与数据存储之间的序列化与反序列化。
逻辑对象:实现管理员对象的逻辑模型。
业务子系统:实现对部门及员工的管理功能。具体包括增加部门、删除部门、列出部门、增加员工、删除员工、修改员工信息、列出部门员工、列出所有员工。
用户界面:显示运营管理子菜单、接受用户输入、向用户显示提示信息、处理结果和必要的反馈。
业务逻辑:具体实现运营管理子菜单的各个功能项,以逻辑对象为载体,在用户界面和数据访问之间传递有关部门及员工的信息数据。
数据访问:实现逻辑对象与数据存储之间的序列化与反序列化。
逻辑对象:实现部门及员工对象的逻辑模型。
数据存储:实现整个管理信息系统的数据持久化。3.2. 体系架构
本案在水平方向上采用三层体系架构。如图所示:
用户界面层:处理与最终用户的交互,既负责从用户处收集信息,也负责向用户展现结果、给出提示或反馈。
业务逻辑层:针对用户界面层所体现的功能项,以数据访问层为基础,实现与业务逻辑相关的算法和流程。
数据访问层:实现对数据存储介质的访问,为业务逻辑层提供数据源,并接受其处理结果。3.3. 逻辑模型
本案在垂直方向上采用三层逻辑模型。如图所示:
接口层:定义各功能模块的抽象接口,降低模块间的耦合性,提高代码复用率,降低维护成本。
实现层:对抽象接口的具体实现。本案用户界面层的接口实现拟采用控制台方式,而数据访问层的接口实现则采用文件系统方式。
逻辑对象层:以逻辑模型的方式对系统中的相关数据加以组织,并构成从用户界面到业务逻辑再到数据访问各层之间的信息载体。逻辑对象包括:管理员、部门和员工。3.4. 平台约束
平台约束 说明 硬件环境 32 位 Intelx86 及其兼容处理器的个人计算机 操作系统 Ubuntu 12.04 LTS 开发工具 GCC4.6.3,C/C++标准库 应用类型 命令行应用程序 用户界面 非全屏模式的控制台字符界面 数据存储 二进制及纯文本文件 平台中立 不要求 交叉编译 不要求 4. 详细设计
4.1 管理子系统
本案管理子系统由用户界面、业务逻辑、数据访问和逻辑对象四部分组成。
其中用户界面、业务逻辑和数据访问又分别包括接口和实现两部分。如图所示:4.1.1. 用户界面
4.1.1.1. 接口类:ManagerView
作为管理子系统用户界面层的接口类,ManagerView 类被定义为纯抽象类,由 4 个纯虚函数组成。
- menu():显示主菜单
- add():处理增加管理员菜单项
- del():处理删除管理员菜单项
- list():处理列出所有管理员菜单项
4.1.1.2. 实现类:ManagerViewConsoleImpl
作为管理子系统用户界面层的实现类,ManagerViewConsoleImpl 从纯抽象类 ManagerView 继承,并对基类中的 4 个纯虚函数提供覆盖版本。
- menu():通过控制台显示主菜单。在一个无限循环中不停显示菜单,接受用户选择,并根据用户所选菜单项调用其它三个接口函数。当用户选择进入运营管理子菜单时,应创建ServiceViewConsoleImpl对象,并调用其menu()接口。当用户选择退出时,终止循环,返回main()函数
- add():通过控制台处理增加管理员菜单项。根据用户输入的管理员用户名和密码创建Manager对象,调用ManagerService::addManager()接口函数增加管理员
- del():通过控制台处理删除管理员菜单项。根据用户输入的管理员ID号,调用ManagerService::deleteManager()接口函数删除管理员
- list():通过控制台处理列出所有管理员菜单项。调用ManagerService::listManager()接口函数获得管理员容器,遍历该容器并列表显示
- ManagerService* service:业务逻辑对象。构造函数中动态创建ManagerServiceImpl对象。
4.1.2. 业务逻辑
4.1.2.1. 接口类:ManagerService
作为管理子系统业务逻辑层的接口类,ManagerService 类被定义为纯抽象类,由 3 个纯虚函数组成。
- addManager():增加管理员
- deleteManager():删除管理员
- listManager():列出所有管理员
4.1.2.2. 实现类:ManagerServiceImpl
作为管理子系统业务逻辑层的实现类,ManagerServiceImpl 从纯抽象类 ManagerService 继承,并对基类中的 3 个纯虚函数提供覆盖版本。
- addManager():增加管理员。将从参数传入的Manager对象加入managers容器
- deleteManager():删除管理员。从managers容器中删除符合特定ID号的Manager对象
- listManager():列出所有管理员。返回managers容器
- ManagerDao* dao:数据访问对象。构造函数中动态创建ManagerDaoFileImpl对象vector managers管理员对象容器。
4.1.3. 数据访问
4.1.3.1. 接口类:ManagerDao
作为管理子系统数据访问层的接口类,ManagerDao 类被定义为纯抽象类,由 2 个纯虚函数组成。
- load():从数据存储读取管理员信息
- save():将管理员信息写入数据存储
4.1.3.2. 实现类:ManagerDaoFileImpl
作为管理子系统数据访问层的实现类,ManagerDaoFileImpl 从纯抽象类 ManagerDao 继承,并对基类中的 2 个纯虚函数提供覆盖版本。
- load():从文件读取管理员信息。以二进制方式整块读取Manager对象,加入从参数传入的管理员容器
- save():将管理员信息写入文件。遍历从参数传入的管理员容器,以二进制方式整块写入每一个Manager对象
4.1.4. 逻辑对象
4.1.4.1. 管理员类:Manager
- int id:ID号
- char name[20]:用户名
- char password[20]:密码
4.2. 业务子系统
本案业务子系统由用户界面、业务逻辑、数据访问和逻辑对象四部分组成。
其中用户界面、业务逻辑和数据访问又分别包括接口和实现两部分。如图所示:4.2.1. 用户界面
4.2.1.1. 接口类:ServiceView
作为业务子系统用户界面层的接口类,ServiceView 类被定义为纯抽象类,由 9 个纯虚函数组成。
- menu():显示运营管理子菜单
- addDept():处理增加部门菜单项
- deleteDept():处理删除部门菜单项
- listDept():处理列出部门菜单项
- addEmp():处理增加员工菜单项
- deleteEmp():处理删除员工菜单项
- modifyEmp():处理修改员工信息菜单项
- listEmp():处理列出部门员工菜单项
- listAllEmp():处理列出部门员工菜单项
4.2.1.2. 实现类:ServiceViewConsoleImpl
作为业务子系统用户界面层的实现类,ServiceViewConsoleImpl 从纯抽象类 ServiceView 继承,并对基类中的 9 个纯虚函数提供覆盖版本。
- menu():通过控制台显示运营管理子菜单。在一个无限循环中不停显示菜单,接受用户选择,并根据用户所选菜单项调用其它八个接口函数。当用户选择返回时,终止循环,返回ManagerViewConsoleImpl的menu()函数
- addDept():通过控制台处理增加部门菜单项。根据用户输入的部门名称创建Department对象,调用Service::addDept()接口函数增加部门
- deleteDept():通过控制台处理删除部门菜单项。根据用户输入的部门ID号,调用Service::deleteDept()接口函数删除部门
- listDept():通过控制台处理列出部门菜单项。调用Service::listDept()接口函数获得部门容器,遍历该容器并列表显示
- addEmp():通过控制台处理增加员工菜单项。根据用户输入的员工姓名、性别和年龄创建Employee对象。再根据用户输入的部门ID号,调用Service::addEmp()接口函数增加员工。
- deleteEmp():通过控制台处理删除员工菜单项。根据用户输入的员工ID号,调用Service::deleteEmp()接口函数删除部门
- modifyEmp():通过控制台处理修改员工信息菜单项。根据用户输入的员工姓名、性别和年龄创建Employee对象,调用Service::modifyEmp()接口函数修改员工信息
- listEmp():通过控制台处理列出部门员工菜单项。根据用户输入的部门ID号,调用Service::listEmp()接口函数列出部门员工
- listAllEmp():通过控制台处理列出所有员工菜单项。调用
- Service::listAllEmp():接口函数列出所有员工
- Service* m_pService:业务逻辑对象。构造函数中动态创建ServiceImpl对象
4.2.2. 业务逻辑
4.2.2.1. 接口类:Service
作为业务子系统业务逻辑层的接口类,Service 类被定义为纯抽象类,由 8 个纯虚函数组成。
- addDept():增加部门
- deleteDept():删除部门
- listDept():列出部门
- addEmp():增加员工
- deleteEmp():删除员工
- modifyEmp():修改员工信息
- listEmp():列出部门员工
- listAllEmp():列出所有员工
4.2.2.2. 实现类:ServiceImpl
作为业务子系统业务逻辑层的实现类,ServiceImpl 从纯抽象类 Service 继承,并对基类中的 8 个纯虚函数提供覆盖版本。
- addDept():增加部门。将从参数传入的Department对象加入m_vecDepts容器
- deleteDept():删除部门。从m_vecDepts容器中删除符合特定ID号的Department对象
- listDept():列出部门。返回m_vecDepts容器
- addEmp():增加员工。根据部门ID号找到该员工所隶属的部门,将参数Employee对象加入该部门的m_vecEmps容器
- deleteEmp():删除员工。依次调用每个部门的deleteEmp()接口函数
- modifyEmp():修改员工信息。依次调用每个部门的modifyEmp()接口函数
- listEmp():列出部门员工。根据部门ID号找到相应的部门,返回该部门的m_vecEmps容器
- listAllEmp():列出所有员工。依次调用每个部门listEmp()接口函数,将处理结果汇总到一个容器中返回
- ServiceDao* m_pDao数据访问对象。构造函数中动态创建ServiceDaoFileImpl对象
- vector m_vecDepts:部门对象容器
4.2.3. 数据访问
4.2.3.1. 接口类:ServiceDao
作为业务子系统数据访问层的接口类,ServiceDao 类被定义为纯抽象类,由 2 个纯虚函数组成。
- load():从数据存储读取部门及员工信息
- save():将部门及员工信息写入数据存储
4.2.3.2. 实现类:ServiceDaoFileImpl
作为业务子系统数据访问层的实现类,ServiceDaoFileImpl 从纯抽象类 ServiceDao 继承,并对基类中的 2 个纯虚函数提供覆盖版本。
- load():从文件读取部门及员工信息。以文本方式读取全部部门和员工信息,加入从参数传入的部门容器
- save():将部门及员工信息写入文件。遍历从参数传入的部门容器,以文本方式写入每一个部门及其所有员工的信息
4.2.4. 逻辑对象
4.2.4.1. 部门类:Department
- deleteEmp():删除本部门的员工。根据从参数传入的员工ID号,从m_vecEmps容器中删除相应员工,没找到则返回false
- listEmp():列出本部门的员工。遍历m_vecEmps容器,将本部门的每位员工逐一加入从参数传入的员工容器
- modifyEmp():修改本部门的员工信息。根据从参数传入的员工对象的ID号属性,从m_vecEmps容器中找到相应员工,更新其信息,没找到则返回false
- int m_nId:ID号
- string m_strName:名称
- vector m_vecEmps:员工对象容器
4.2.4.2. 员工类:Employee
- int m_nId:ID号
- string m_strName:姓名
- bool m_bGender:性别,true表示男性,false表示女性
- int m_nAge:年龄
4.3. 基础设施及辅助工具
- generator_MgrId():生成唯一的管理员ID号。
- generator_DeptId():生成唯一的部门ID号。
- generator_EmpId():生成唯一的员工ID号。
- 注意:从id.dat配置文件中读取上次生成的ID号,将其加1后重新写入,同时返回新生成的ID号。*
4.4. 配置文件
- id.dat:唯一ID号配置文件。保存最后一次生成的ID号,每次新生成的ID号即在此基础上加1。
4.5. 数据存储
managers.dat:管理员信息数据库。以二进制形式保存全部Manager对象
services.dat:部门及员工信息数据库。形如:1004 研发部 103 1008 王曦文 109 1009 李政 136 1010 杨超 135 1005 销售部 102 1012 林豪 025 1006 财务部 101 1011 戚钧恒 02811004 研发部 103
21008 王曦文 109
31009 李政 136
41010 杨超 135
51005 销售部 102
61012 林豪 025
71006 财务部 101
81011 戚钧恒 028
- 部门记录,包括三个字段:部门ID号、部门名称和该部门的员工人数。程序可以以部门员工人数字段的值作为后续读取员工记录的循环控制上限;
- 每个部门记录下面紧跟着隶属于该部门的员工记录,包括四个字段:员工ID号、员工姓名、员工性别(1表示男性,0表示女性)和员工年龄;
- 为了便于程序通过标准I/O流进行格式化访问,各字段之间以空格分隔。
5. 文件组织
5.1. 代码文件
5.1.1. 管理子系统
- managerview.h:定义ManagerView抽象基类
- managerview_console_impl.h:声明ManagerViewConsoleImpl类
- managerview_console_impl.cpp:实现ManagerViewConsoleImpl类
- managerservice.h:定义ManagerService抽象基类
- managerservice_impl.h:声明ManagerServiceImpl类
- managerservice_impl.cpp:实现ManagerServiceImpl类
- managerdao.h:定义ManagerDao抽象基类
- managerdao_file_impl.h:声明ManagerDaoFileImpl类
- managerdao_file_impl.cpp:实现ManagerDaoFileImpl类
- manager.h:声明Manager类
- manager.cpp:实现Manager类
5.1.2. 业务子系统
- serviceview.h:定义ServiceView抽象基类
- serviceview_console_impl.h:声明ServiceViewConsoleImpl类
- serviceview_console_impl.cpp:实现ServiceViewConsoleImpl类
- service.h:定义Service抽象基类
- service_impl.h:声明ServiceImpl类
- service_impl.cpp:实现ServiceImpl类
- servicedao.h:定义ServiceDao抽象基类
- servicedao_file_impl.h:声明ServiceDaoFileImpl类
- servicedao_file_impl.cpp:实现ServiceDaoFileImpl类
- department.h:声明Department类
- department.cpp:实现Department类
- employee.h:声明Employee类
- employee.cpp:实现Employee类
5.1.3. 基础设施及辅助工具
- main.cpp:定义main()函数
- emis.h:声明全局变量
- emis.cpp:定义全局变量
- tools.h:声明工具函数
- tools.cpp:定义工具函数
5.2. 脚本文件
- makefile:项目制作脚本