1、第17章 酒店管理系统 本章利用前面学过的知识,结合.NET三层结构的开发思想,完成一个C/S结构的实用的酒店管理系统,来巩固和加深前面学过的编程技术。本章还通过系统的设计和实现介绍了一些编程方面的重要技巧,内容涉及到ADO.NET技术、数据验证技术、参数传递、数据显示控件、容器控件等。本章主要内容:酒店管理系统的系统分析。用户管理模块的设计和实现。酒店基础信息设置模块的设计和实现。酒店业务管理模块的设计和实现。17.1 系统分析 作为酒店管理的一个工具,该系统实现了酒店管理的基本功能,如添加、删除、修改住房信息,添加、删除、修改客人信息等。17.1.1 需求分析需求分析是开发应用系统的第一步
2、,通过需求分析可以了解客户需要什么样的程序,需要完成什么功能。需求说明书描述系统的总体要求,并且作为各方面沟通的依据,也为下一步工作提供基准。系统开发人员要按照需求说明书完成相应的功能。读者可以查找相关书籍学习需求说明书的标准描述方式,在此重点阐述系统的分析和设计。“酒店管理系统”用于管理和维护酒店的基本信息,酒店工作人员登录系统后可以拥有该系统的所有功能,方便进行酒店内部管理。该系统使用数据库存放数据,图17.1显示了系统的功能设计。17.1.2 系统设计本系统的总体架构采用三层架构模型,分为表示层、业务逻辑层、数据访问层,其中表示层负责界面的显示,用于显示数据和接收用户输入的数据,为用户提
3、供交互式操作界面;业务逻辑层是表示层和数据访问层之间通信的桥梁,主要负责数据的传递和处理;数据访问层主要实现对数据的保存和读取操作。该系统比较简单,因此不考虑使用接口和反射技术。三个模块之间直接使用对象或者数据集进行通信。本系统三层架构如图17.2所示。17.1.3 数据库设计我们设计的酒店管理系统属于信息管理系统,其中的功能都是围绕数据库实现的,所以数据库的设计非常重要。在VS2008中打开“服务器资源管理器”窗口,右击“数据连接”选项,单击“创建新的数据库”选项,即可开始创建系统需要的数据库,数据库名称为HotelManager,包括6张表,表的名称和结构分别说明如下。客人信息表(Gues
4、t)的表结构见表17.1。该表用于存放入住酒店的客人信息,通过这个表可以记录入住酒店客人的详细信息,以及客人到达和离开酒店的时间。17.2 实体类的实现 前面一个示例程序中,数据传递是使用DataSet实现的,DataSet不具备良好的面向对象的特性,使用起来不够直观、方便,而且DataSet的核心结构与数据库的核心结构完全相同,使用DataSet传递数据就把数据结构完全暴露在表示层和业务逻辑层,不利于数据安全。实体类具有面向对象的基本特征,是业务对象的基础。在三层之间通过实体类传递数据具有很大的灵活性,有助于项目的维护、扩展,更能体现三层结构的优势。本系统中,数据库HotelManager的
5、五张表分别转换为五个实体类,具体内容详述如下。17.2.1 HotelUser实体类 HotelUser实体类对应于数据库中的HotelUser数据表,将其转换成面向对象的表示形式,类图如17.4所示。17.2.2 Guest实体类 Guest实体类对应于数据库中的Guest表,类图如图17.5所示。17.2.3 GuestCategory实体类 GuestCategory实体类来源于数据表GuestCategory,该类比较简单,类图如图17.5所示。17.2.4 Room实体类 Room实体类对应数据库中的表Room,类图如图17.6所示。17.2.5 ToomType实体类 RoomTy
6、pe实体类对应数据表RoomType,其类图如图17.7所示。17.3 界面设计 应用程序的界面是展示给用户的,为用户提供和系统进行交互的功能,对用户界面进行良好的设计非常重要,既可以完成程序的功能,又能使用户方便的使用。本节首先以图片的形式将系统的界面展现出来,帮助您对本系统有一个初步直观的了解。17.3.1 用户登录面 用户登录界面为系统用户提供交互,输入用户名和密码,登录本系统。界面设计如图17.8所示。为了是界面更加友好,美观,设计时使用了图片作为背景。17.3.2 主界面系统主界面采用通用的模式,包括菜单栏、工具栏等控件。主界面是多文档应用程序,采用了默认的控件颜色,界面中最上面是菜
7、单,然后是工具栏。本系统属于内部管理使用,必须登录后才能拥有系统的使用权限,否则所有的工具和菜单都处于不能使用的状态。如图17.9所示。17.3.3 客房类型设置界面此界面用于完成客房类型的检索、增加、修改、删除功能。界面设计如图17.10所示。该界面中用到了菜单栏、工具栏、DataGridView控件、分组框(GroupBox)、分组面板(Panel)等控件。单击“新增”或“修改”按钮,可显示“Panel”面板,在该面板中添加文本框、组合框等对客房信息进行修改。界面如图17.11所示。17.3.4 客房信息界面客房信息界面设计是为了方便客房信息维护,采用的设计风格和客房类型设置界面基本相同,
8、如图17.12所示。单击“新增”、“修改”、“删除”按钮,均可打开相应编辑面板,如图17.13所示。单击“取消”按钮可隐藏编辑面板。该界面中控件和相关属性的设定和客房类型设置界面相似,这里不再列出详细说明,请参照表17.8完成。17.3.5 客人管理界面客人管理界面提供对客户的信息进行维护,包括增、删、改、查操作,设计风格沿用上边两个界面的方式,如图17.14所示。单击“新增”、“修改”、“删除”按钮,均可打开相应编辑面板,如图17.15所示。单击“取消”按钮可隐藏编辑面板。单击“修改”、“删除”按钮时,需要首先在DataGridView控件中单击需要修改或删除的信息,将其信息显示在打开的编辑
9、面板中,可进行修改操作,也可删除。该界面中控件和相关属性的设定和客房类型设置界面相似,这里不再列出详细说明,请参照表17.8完成。17.3.6 用户管理界面 用户管理界面用于完成用户的增、删、改、查功能,界面设计如图17.16所示。单击“新增”、“修改”、“删除”按钮,均可打开相应编辑面板,实现对用户信息的修改。17.4 实现数据访问层 本系统采用.NET三层架构的思想构建,由数据访问层完成对数据库的操作。由于数据库的访问包含增、删、改、查等多种操作,所以在每一个类中包含很多方法,具体每一类中包含哪些方法根据需求而定。为了调用方法简单化,在数据访问层中所有的类和方法均为静态类和静态方法。17.
10、4.1 数据库通用操作类(DBHelper.cs)由于系统中对于数据库操作都需要处理连接字符串、创建连接、执行查询、更新等通用操作,为了提高代码的复用性,创建DBHelper.cs类完成数据库的通用操作。定义了连接数据库的字符串,创建数据库连接。方法中有:执行无参数的sql语句的方法、执行有参数的sql语句等方法。17.4.2 用户管理数据访问(HotelUserService.cs用户管理的数据访问需要实现对用户表的增、删、改、查操作,使用实体对象传递数据,使用IList传递实体对象集合。用户管理数据访问示例如代码17-7所示。该类中包含的方法有:AddHotelUser(HotelUser
11、 hotelUser):用户对象作为参数,实现添加新用户的功能。DeleteHotelUser(HotelUser hotelUser):将用户对象作为参数,实现删除用户的操作。DeleteHotelUserByUserID(int userID):根据用户ID删除用户的方法。ModifyHotelUser(HotelUser hotelUser):将用户对象作为参数,更新用户信息。GetAllHotelUsers():获取所有用户信息。GetHotelUserByUserID(int userID):根据用户ID获取用户信息。GetHotelUserByUserName(string use
12、rName):根据用户名获取用户信息。17.4.3 客房信息数据访问(RoomService.cs)客房信息数据访问类和用户管理数据访问的方法编写很相似,都是完成对数据库的增、删、改、查操作,只是针对不同的应用,传递的参数不同。示例代码如代码17-8所示。说明:在下面的方法中,创建DataReader对象时都采用了using关键字,这是using的一种用法,using(SqlDataReader dataReader=DBHelper.GetReader(sql),using括号中创建的对象,在执行到using语句块的末尾时会自动释放该对象。本例中创建的DataReader对象由于使用了usi
13、ng关键字,在语句执行完毕后会自动释放,就不需要显式关闭即不需要执行DataReader对象的Close()方法。该类中包含的方法如下:GetAllRooms():得到客房信息集合。GetRoomByRoomId(int roomId):根据客房ID得到客房信息实体对象。GetRoomListByRoomNumber(string roomNumber):根据客房名称得到客房信息集合。GetRoomIdByRoomNo(string roomNo):根据房间号得到客房实体对象。DeleteRoomByRoomId(int roomId):根据客房ID删除客房信息。ModifyRoom(Room
14、 room):修改客房信息。AddRoom(Room room):增加客房信息。17.4.4 客房类型数据访问(RoomType.cs)客房类型数据访问(RoomType.cs)实现客房类型的数据库操作,编写方法和客房信息数据访问基本相同,示例代码如代码17-9所示。该类包含的方法如下:GetAllRoomTypes():得到客房类型信息集合。GetRoomTypeListByTypeName(string typeName):根据客房类型名称得到客房类型列表。GetTypeNameByTypeID(int typeID):根据客房类型ID得到客房类型名称。GetRoomTypeByTypeI
15、D(int typeId):根据客房类型ID得到客房实体对象。ModifyRoomType(RoomType roomType):修改客房信息。DeleteRoomTypeByTypeId(int typeId):删除客房类型信息。AddRoomType(RoomType roomType):增加客房类型信息。17.4.5 客人管理数据访问(Guest.cs)客人管理数据访问类实现对客人表(Guest)的查询、修改、删除等操作,负责与数据库之间的交互,该类示例代码如代码17-10所示。为了使读者能够灵活掌握sql语句的编写,在此例中没有使用客房信息和客房类型示例代码中可变字符串的方法生成sql
16、语句,而是直接使用参数类的方法,在代码第18行,使用参数创建了sql语句,在代码第22行到31行,使用SqlParameter类型的数组存储sql语句中的参数,调用DBHelper类中的方法执行sql语句。17.4.6 客人类型数据访问(GuestCategory.cs)客人类型数据访问(GuestCategory.cs)的功能比较简单,只要能够根据ID获得客户类型就可以,示例代码如代码17-11所示。该类中包含的方法如下:GetAllGuestCategories():17.5 实现业务逻辑层 业务逻辑层负责数据的传递,在实现业务逻辑层之前,先概括一下实现的步骤:(1)在业务逻辑处理类中引用
17、数据访问层、实体层的命名空间。(2)实例化实体对象。(3)调用数据访问功能。(4)实现业务逻辑。17.5.1 用户管理业务逻辑类(HotelUserManage.cs)用户管理业务逻辑类(HotelUserManage.cs)用来处理用户管理的业务逻辑,在用户管理数据访问HotelUserServ.cs类和用户管理界面之间进行数据传递。添加用户操作时,判断用户是否存在,如存在同名用户,则不允许添加。删除用户、修改用户都是通过调用HotelUserService.cs类中的方法实现。示例代码如代码17-12所示。(详细内容请参照本书)17.5.2 客房信息管理业务逻辑(RoomManager.c
18、s)客房信息管理业务逻辑(RoomManager.cs)负责在客房信息管理数据访问和客房信息界面之间进行数据传递,通过调用RoomService.cs中的方法实现,示例代码如代码17-13所示。(详细内容请参照本书)17.5.3 客房类型业务逻辑(RoomTypeManager.cs)客房类型业务逻辑负责在客房类型数据访问层和界面之间进行数据传递,和客房信息业务逻辑相同,具有增、删、改、查功能。示例代码如代码17-14所示。(详细内容请参照本书)17.5.4 客人管理业务逻辑(GuestManager.cs)客人管理业务逻辑负责在客人管理数据访问层和界面之间进行数据传递,和客房信息业务逻辑相同
19、,具有增、删、改、查功能。示例代码如代码17-15所示。(详细内容请参照本书)17.5.5 客人类型管理业务逻辑(GuestCategory.cs)客人类型表比较简单,用到的方法也较少,主要实现检索功能。示例代码如代码17-16所示。17.6 实现表示层数据绑定 上面已经设计好了窗体,根据窗体需求实现了数据访问层和业务逻辑层的功能,本节完成界面也就是表示层的数据绑定,与数据库能够真正地发生交互。17.6.1 用户登录 用户登录表示层实现的功能主要有:判断输入的登录名和密码是否为空,判断输入的登录密码是否与根据登录ID得到的密码相同,如果相同则登录成功,返回主界面。用户登录的代码如代码17-17
20、所示。本项目采用三层架构构建应用系统,界面层只能直接调用业务逻辑层,不能调用数据访问层,各层之间通过实体类传递数据,编写程序时首先引用命名空间HotelManager.Models和HotelManager.BLL,然后调用HotelUserManager.cs中的方法实现登录功能。17.6.2 主界面 本系统将首先启动的界面设置为主界面,用户登录成功后主界面中按钮和菜单才可以使用,如果取消登录或登录失败,主界面中的菜单和按钮基本都不可用。主界面是子界面的容器,通过单击主界面上的菜单或按钮,打开相应的子窗体,实现程序退出功能。主界面中的各个功能都是通过给事件编写代码实现。17.6.3 客房类型
21、设置窗体载入时在数据列表控件DataGridView中显示客房类型的详细信息,隐藏编辑面板,单击“新增”、“修改”、删除时可以显示。鼠标在DataGridView控件中单击时,也可打开编辑面板,将鼠标所在位置的一条记录传送到编辑面板中相应的文本框、组合框中,以利于修改、删除等操作。窗体载入时,将客房信息绑定到DataGridView控件上,代码17-18演示此功能实现的代码。17.6.4 客房信息设置 客房信息管理界面实现客房信息的维护,提供客房信息查询、删除、修改功能,和客房类型设置的功能基本相同,首先编写了显示编辑区的方法VisibleEditSection()、清空编辑区的方法Clear
22、EditSection()。17.6.5 用户管理 用户管理负责对用户信息进行维护,包括增、删、改、查功能,窗体载入时将数据显示在DataGridView控件中,并将编辑区设为不可见。单击“新增”按钮时将编辑区显示出来,同时清空。修改、删除功能和前面的代码大同小异,就不再详述。17.6.6 客人管理 客人管理模块完成对客人信息的维护和管理,通过调用客人管理业务逻辑层实现数据的增、删、改、查,代码编写方法和思路与前面的客房类型设置基本相同,不再详述。17.7 小结 本章实现了一个完整的酒店管理系统,只是本章的实例较为简单。编写一个完整的项目是非常复杂和枯燥的,很多都是重复性劳动。学习完本章,对.NET三层架构的使用方法和优势有更深刻的理解和体会,在大型项目中使用三层结构更具优势。本章的例子采用数据实体在三层之间进行数据传递,几乎没有用到数据集,上一章的实例几乎全部使用数据集作为数据源,这两种方法各有优势,在目前的.NET项目开发中也是各有市场,可以根据不同的情况选择使用。