Java图书管理系统的设计与实现
------整合设计模式与Java基础的实战开发
内容摘要
本项目围绕图书管理的核心需求,设计并实现了一款基于Java语言的图书管理系统。系统整合Java基础语法与单例模式、工厂模式、代理模式三大设计模式,实现了管理员与普通用户的权限分离及业务闭环。核心功能涵盖图书上架、更新、下架、借阅、归还、查询等关键流程,并通过文件读写完成数据持久化存储。通过项目开发,完成了从框架搭建、模块划分、核心类设计到功能实现与测试的完整流程,有效提升了代码的可扩展性与可维护性,为图书管理场景提供了高效、便捷的解决方案。
关键词:Java 图书管理系统 设计模式 数据持久化 权限控制
一、绪论
在信息化时代,传统人工图书管理方式存在效率低下、数据易丢失、权限管理混乱等问题,已无法满足图书管理的规范化、高效化需求。基于Java语言的图书管理系统凭借跨平台性、稳定性及良好的扩展性,成为解决这一问题的优选方案。本项目通过整合Java核心技术与设计模式,构建功能完善、架构清晰的图书管理系统,实现图书管理全流程的数字化处理,为管理员和用户提供便捷的操作体验。
(一)研究背景与意义
1. 研究背景
随着图书资源的不断丰富,图书馆、书店等场所对图书管理的精细化、高效化要求日益提高。传统人工登记、纸质记录的管理方式存在查询耗时、统计困难、借阅状态更新不及时等弊端,容易导致管理混乱和资源浪费。而现有部分图书管理系统存在功能单一、代码可维护性差、权限控制不严谨等问题,难以适应多样化的管理需求。因此,开发一款整合先进技术、架构合理、功能完备的图书管理系统具有重要的现实意义。
2. 研究意义
( 1 ) 理论意义
本项目致力于将设计模式与 Java 基础语法深度融合,在图书管理系统从架构设计到功能实现的全流程中,系统性运用单例、工厂和代理等核心设计模式。架构设计阶段考虑其应用,模块开发按规范构建,功能实现确保有效落地。全流程运用可应对传统 Java 项目常见问题,如代码耦合度高、功能扩展性差、模块复用性低等。
实践表明,设计模式可增强代码可维护性与灵活性。单例模式保证系统核心资源统一管理,提高使用效率和安全性;工厂模式减少对象创建与业务逻辑的耦合,使对象创建更灵活可控;代理模式实现权限控制精细化。
本项目的技术方案和实践经验,对类似 Java 项目(如学生信息管理系统、商品库存管理系统)开发有重要参考价值。开发者可在项目初期借鉴经验,构建高内聚、低耦合的优质架构,提高开发效率与质量,减少错误,加快开发进度。
(2) 实践意义
该系统实现了图书管理核心流程自动化处理,提高了图书上架、借阅、归还等操作效率,节省人力、减少操作时长。同时,系统全面规范权限管理,通过精准设置与管理机制,避免越权访问,增强图书管理体系规范性。此外,系统能保障图书管理数据安全完整,在存储、处理、传输时采用先进技术与严格管控措施,防止数据丢失、泄露及恶意篡改。而且,因系统实现自动化与规范化管理,降低了人工管理成本,原本多人长时间投入的工作现在系统可高效完成。总之,这套系统解决了图书管理诸多实际问题,实用价值强,能显著提升图书管理工作并带来便利。
(二)研究现状
目前,市场上图书管理系统种类繁多,形态丰富,涵盖传统桌面应用和先进 Web 应用等。部分系统基于 Java 技术开发,其功能强大、适用性广。但多数系统开发中,开发人员重功能实现,轻代码架构设计与设计模式应用。代码架构设计如房屋框架,设计模式是构建方法,缺乏重视使系统后期维护和功能扩展困难,修改或添加新功能时操作难、效率低。
与此同时,一些小型图书管理工具暴露出诸多问题。这些工具数据存储不稳定,可能出现丢失、损坏等现象,影响系统正常使用;且权限划分模糊,不同角色用户使用系统时权限界定不明确,导致管理混乱。这种状况使它们无法满足多角色协同管理需求,难以实现不同角色间高效、有序协作。
本项目针对现有系统不足开展。实施中,注重架构设计与设计模式应用,精心规划代码架构、合理运用设计模式,使系统底层结构更稳固合理。同时,强调权限分离与数据持久化,明确划分角色权限,确保数据稳定存储。致力于打造实用且具扩展性的图书管理系统,既能满足当前图书管理需求,又能适应未来市场与业务变化进行扩展升级。
(三)项目研究内容与目标
1. 研究内容
本项目聚焦基于 Java 语言的图书管理系统设计与实现,旨在借助 Java 打造高效、稳定且易管理的平台。核心内容包括:一是精心设计系统架构、合理划分模块,提高系统可维护性与可扩展性,使模块协作更顺畅;二是应用单例、工厂和代理三大设计模式,优化代码结构,提高复用性与可维护性,增强系统性能;三是进行管理员与普通用户权限分离设计,赋予不同操作权限,确保数据安全与操作规范;四是开发图书管理核心功能,实现图书添加、删除等操作及读者借阅、归还流程,满足实际管理需求;五是实现数据持久化,有效存储和管理数据,确保完整性与持久性,为系统稳定运行提供支撑。
2. 研究目标
全面且深入地掌握 Java 项目从最初的框架搭建直至各项功能成功落地的一整套完整流程,涵盖框架选型、架构设计、模块划分以及代码实现等各个关键环节,确保对整个项目的开发过程有精准把控;透彻理解设计模式在实际开发过程中的具体应用场景以及其所具备的重要价值,清晰知晓在何种情形下运用何种设计模式能够优化代码结构、提升系统的可维护性和扩展性;熟练实现图书管理系统中诸如上架、更新、下架、借阅、归还、查询等一系列核心功能,确保每一个功能都能稳定且高效地运行,满足实际业务需求;精心完成管理员与普通用户之间的业务闭环,通过合理的业务流程设计和交互逻辑,保证权限控制严谨,不同角色的用户只能访问和操作其被授权的功能和数据;巧妙地通过文件存储的方式实现数据持久化,建立完善的数据存储和恢复机制,保证在各种情况下数据都不会丢失,为系统的稳定运行提供坚实的数据保障。
二、系统分析
(一)可行性分析
1. 技术可行性
本项目基于 Java 基础语法开发,在 Java 编程里,基础语法是搭建项目的基石。项目运用的核心技术包括类与对象、封装/继承/多态、异常处理等。类与对象是面向对象编程核心,用于抽象和建模现实事物;封装、继承、多态是面向对象编程三大特性,分别可提高代码安全性与可维护性、实现代码复用与扩展、增强代码灵活性与可扩展性;异常处理能捕获和处理异常,保证程序稳定性与健壮性。这些技术在软件开发行业成熟且应用广泛。
设计模式应用在本项目中很重要,它是软件开发通用解决方案,有成熟理论和丰富案例,合理运用可提高代码可读性、可维护性和可扩展性。
数据处理方面,数据持久化是关键。本项目用 FileUtils.jar 实现文件读写,它功能强大,简化开发流程;采用 JSON 序列化实现对象与字符串相互转换,JSON 格式轻量级,便于数据传输和存储。这些技术有完善开发文档,工具支持丰富,技术门槛适中,项目在技术层面具备可行性。
2. 经济可行性
本项目开发无需复杂硬件设备支撑,复杂硬件伴随高昂购买、维护和能源消耗成本,项目设计时已考虑经济因素,避免依赖高端复杂硬件。同时,也无需支付高昂软件授权费用,许多软件需购买授权增加开发成本,而本项目采用免费开源开发环境,功能强大且有社区支持,能满足开发需求。
从项目全生命周期看,后期维护成本也是重要考量。本项目采用成熟简洁技术架构,代码结构清晰易维护,后期维护成本低。系统上线后能带来显著效益提升,一方面可降低人工管理成本,传统管理模式需大量人力处理数据、管理信息,效率低且易出错,本系统可自动化完成工作;另一方面能提高工作效率,让业务流程更顺畅高效。综合开发成本和上线后效益,本项目成本效益比良好,经济上可行。
3. 操作可行性
本系统通过命令行交互实现用户与系统的交互,这是一种简洁高效的方式,无需复杂图形界面,输入特定命令即可完成操作,操作流程简洁清晰,用户易理解掌握。针对不同用户角色,系统为管理员和普通用户分别设置操作菜单指引。管理员负责系统管理维护,操作菜单提供系统配置、用户管理等功能;普通用户使用基本业务功能,操作菜单针对业务功能简化优化。二者均可依菜单指引快速找到所需功能。因操作流程简单直接,用户无需复杂培训即可上手,所以本系统在操作上具有较高可行性。
(二)需求分析
1. 功能需求
(1)管理员角色:管理员要具备多项重要功能,包括图书上架(将新采购或录入图书添加到系统供借阅)、图书信息更新(修改图书相关信息)、图书下架(移除损坏、过期等不适合借阅的图书)、借阅统计(统计分析一定时期内图书借阅情况)、热门图书查询(定位受欢迎图书)、库存管理(监控库存数量并合理安排采购)。同时拥有共用功能,如图书查找(通过书名等信息快速找到图书)、显示所有图书(展示系统内全部图书信息)、退出系统(安全结束操作会话)。
(2)普通用户角色:普通用户需具备特定功能,有图书借阅(完成借阅操作)、图书归还(在期限内归还图书)、个人借阅记录查询(查看借阅历史)、图书搜索(查找特定图书)。也拥有与管理员相同的共用功能,如图书查找、显示所有图书、退出系统(正常结束使用状态)。
(3)数据存储需求:系统需对关键信息持久化存储,要将图书数据(包括书名等基本信息)和借阅记录(包含借阅时间等借阅行为信息)存储到文件中,以保证程序重启后数据不丢失,确保系统正常运行和数据完整性。
(4)权限控制需求:系统设计和管理中,要严格区分管理员与普通用户操作权限,保证系统安全和数据准确。普通用户无权执行图书上架等管理员专属功能,管理员也不能随意执行个人借阅记录查询等普通用户特定功能,避免越权操作,保障系统稳定运行和数据安全。
2. 非功能需求
(1)稳定性需求:系统需稳定持续运行,避免因异常状况崩溃,如异常输入、文件读写错误等。为此,系统应具备异常处理能力,及时捕获、分析和处理异常,确保稳定运行。
(2)可扩展性需求:代码架构设计应遵循面向对象原则,以提高可维护性、可复用性和可扩展性。考虑到系统后续可能扩展功能,如添加用户注册、图书预约功能等,设计要确保添加新功能时不影响现有系统。
(3)易用性需求:系统操作流程应简洁明了,操作步骤清晰易懂,交互提示准确。在用户进行关键操作时,系统应给出提示,告知操作要求和可能结果,以提高用户使用效率和体验。
三、系统设计
(一)系统目标
1. 功能目标
全面实现图书管理核心流程的全方位覆盖,将图书管理过程中的各个关键环节都纳入其中,无论是图书的采购、编目、上架,还是借阅、归还、续借等流程,都能做到无一遗漏。充分满足管理员与普通用户的差异化需求,对于管理员而言,提供诸如批量图书信息录入、数据统计分析、用户权限管理等高级功能;对于普通用户,则着重提供便捷的图书查询、预约借阅、个人借阅信息查看等服务。同时,通过严格的测试、优化和监控机制,确保图书管理系统的各项功能都能够稳定、准确地运行,避免出现系统卡顿、数据错误、功能异常等问题,为管理员和普通用户营造一个高效、可靠的图书管理环境。
2. 技术目标
全面整合 Java 编程语言中的基础语法知识,包括但不限于变量的声明与使用、数据类型的区分、控制流程语句的运用等,同时深度融合三大设计模式,即单例模式、工厂模式和观察者模式等,精心构建出一个层次极为清晰、耦合度显著降低的系统架构。通过这样的架构设计,能够极大地提升代码在后续开发与维护过程中的可维护性,使得开发人员可以更加轻松地对代码进行修改和优化;同时也显著增强了代码的可扩展性,为系统未来的功能拓展和业务增长提供坚实可靠的基础。
3. 数据目标
实现对图书数据以及借阅记录进行持久化存储这一重要操作,通过一系列科学合理且行之有效的技术手段和管理措施,来确保这些数据能够长期稳定地保存下来。同时,要高度重视数据的完整性与安全性,运用严格的数据校验机制、可靠的加密技术以及完善的访问控制体系等,全方位保障数据在存储和使用过程中不出现任何缺失、损坏或者被非法获取的情况,从而为相关业务的正常开展和后续的数据利用提供坚实可靠的基础。
4. 用户目标
为用户提供一种简洁且直观的操作界面,这种界面设计能够让用户轻松地识别各项功能与操作流程。通过这样的设计,极大地降低了用户使用该系统或产品的门槛,即使是初次接触的用户也能快速上手。同时,还能显著提升用户在操作过程中的体验,使用户在操作时更加流畅、便捷,减少不必要的困扰和时间浪费。
(二)功能框架
系统的功能框架是依据角色进行划分的,这种划分方式能够清晰地界定不同角色在系统中所拥有的操作权限和可使用的功能范围。整个系统功能框架主要分为三大类功能模块,分别是管理员功能模块、普通用户功能模块以及共用功能模块。下面将对这几个功能模块的具体情况进行详细说明,具体如下:
表3-1 系统功能框架表
|------|------|---------------------|
| 角色 | 功能模块 | 具体功能 |
| 管理员 | 图书管理 | 图书上架、图书更新、图书下架、库存管理 |
| | 统计查询 | 借阅统计、热门图书查询 |
| | 共用功能 | 图书查找、显示所有图书、退出系统 |
| 普通用户 | 借阅管理 | 图书借阅、图书归还、个人借阅记录查询 |
| | 图书查询 | 图书搜索 |
| | 共用功能 | 图书查找、显示所有图书、退出系统 |
图3-1以一种极为直观的方式清晰地呈现了在图书管理系统当中"管理员"与"普通用户"所拥有的功能权限相关情况。具体而言,管理员在这个系统里拥有一系列专属的操作权限,他们可以执行诸如图书上架、图书信息更新、图书下架以及库存管理等特定操作。这些操作对于维护图书管理系统的正常运行以及图书资源的合理调配起着至关重要的作用。与此同时,管理员也和普通用户共同使用一些功能,像图书查找功能,用户能够通过该功能在众多图书中快速定位自己所需的图书;显示所有图书功能,能让用户全面了解系统内现有的图书资源;还有退出系统功能,方便用户在使用完毕后安全退出系统。
而普通用户在图书管理系统中也具备一些属于他们自己的专属操作。比如图书借阅功能,普通用户可以凭借该功能从系统中借走自己感兴趣的图书;图书归还功能,方便用户在借阅期限结束后将图书归还给系统;个人借阅记录查询功能,用户能够通过此功能查看自己以往的借阅历史;以及图书搜索功能,帮助用户精准找到自己想要借阅的图书。通过图中的线条巧妙地将不同的角色与对应的功能进行关联,能够非常清晰地区分两类用户的专属功能以及共用功能,从而明确了该图书管理系统中不同角色的权限边界,让系统的使用规则更加一目了然。

图3-1图书管理系统用户功能用例图
(三)系统开发环境
1. 硬件环境
CPU:Intel Core i5及以上;
内存:4GB及以上;
硬盘:至少10GB可用空间;
操作系统:Windows 10/11、macOS等支持Java开发的操作系统。
2. 软件环境
开发工具:IntelliJ IDEA 2020.3及以上版本;
Java版本:JDK 8及以上;
依赖包:FileUtils.jar(用于文件读写);
构建工具:无(纯Java原生开发);
数据存储:文本文件(allbook.txt、borrowedbook.txt)。
(四)核心技术与设计模式选型
1. 核心技术
( 1)JAVA基础语法
在Java编程领域,Java基础语法是至关重要的部分。像类与对象这一核心概念,类是对一类事物的抽象描述,而对象则是类的具体实例,它们共同构建起程序的基本结构。封装、继承和多态这三大特性更是Java面向对象编程的精髓所在。封装能够将数据和操作数据的方法绑定在一起,隐藏内部实现细节,提高代码的安全性和可维护性;继承允许一个类继承另一个类的属性和方法,实现代码的复用和扩展;多态则让不同的对象可以对同一消息做出不同的响应,增强了代码的灵活性和可扩展性。此外,异常处理也是Java基础语法中不可或缺的一部分,它可以对程序运行过程中可能出现的异常情况进行捕获和处理,保证系统的稳定性。这些Java基础语法的各个方面,共同构成了系统开发的坚实基础。
(2)数据持久化
在软件开发过程中,数据持久化是一个关键的需求。为了实现数据的持久化存储,我们采用了FileUtils.jar这个工具。FileUtils.jar是一个功能强大的工具包,它提供了一系列方便的方法来实现文件的读写操作。通过使用FileUtils.jar中的相关方法,我们可以轻松地将数据写入到文件中,也能够从文件中读取所需的数据。这种方式使得数据可以在系统运行的不同阶段或者不同环境下进行保存和恢复,从而完成数据持久化存储的任务,确保数据的安全性和可靠性。
(3)JSON序列化
JSON序列化在数据处理和存储过程中具有重要的作用。它的主要功能是实现Java对象与字符串之间的相互转换。当我们需要将Java对象存储到文件中或者在网络中传输时,由于文件和网络传输通常只能处理文本数据,所以需要将Java对象转换为字符串形式,这就是JSON序列化的过程。而当我们从文件中读取数据或者接收到网络传输的数据后,又需要将字符串形式的数据转换回Java对象,这就是JSON反序列化的过程。通过JSON序列化和反序列化,我们可以方便地将数据在文件中进行存储和读取,提高了数据处理的效率和灵活性。
(4)日期转化
在实际的软件开发中,日期处理是一个常见的需求。为了实现准确的时间计算,我们使用了Java中的LocalDate和Instant类。LocalDate类主要用于处理日期,它提供了丰富的方法来进行日期的计算和比较,例如计算两个日期之间的差值、获取指定日期的年、月、日等信息。Instant类则主要用于处理时间戳,它可以精确到纳秒级别,非常适合用于记录和计算时间点。在实际应用中,我们可以利用这两个类来实现各种时间计算功能,比如记录商品的上架时间、计算图书的借阅期限等。通过使用LocalDate和Instant类,我们可以确保时间计算的准确性和可靠性。
2. 设计模式选型
( 1 )单例模式
单例模式作为一种重要的设计模式,它的主要作用在于确保像 Scanner(这是一种常用的输入工具,在程序中用于接收用户的输入信息)、Library(这可是图书管理系统里的核心部分,负责对图书的各种信息进行管理、存储以及查询等操作)这类关键的类在整个系统运行过程中仅仅存在一个实例。通过这种方式,单例模式为这些类提供了一个全局统一的访问点。也就是说,系统内的各个部分都能够通过这个唯一的访问点来获取和使用这些类的实例。而这样做的一个重要好处就是能够避免资源的不必要浪费。因为如果不采用单例模式,可能会在系统的不同地方多次创建这些类的实例,这会占用大量的系统资源,而采用单例模式就可以有效杜绝这种情况的发生。
(2) 工厂模式
工厂模式是一种在软件开发领域广泛应用的设计模式,它的核心作用在于将用户对象的创建操作与使用操作进行有效的分离。在实际的编程场景中,我们常常会面临创建不同类型用户对象的需求,例如管理员用户和普通用户。为了更好地实现这一需求,我们可以借助具体的工厂类来完成。这里,我们使用 AdminUserFactory 和 NormalUserFactory 这两个专门的工厂类,其中 AdminUserFactory 承担着创建管理员用户对象的任务,而 NormalUserFactory 则负责创建普通用户对象。通过这种方式,将对象的创建逻辑封装在各自的工厂类中,避免了在使用对象的代码里直接进行对象创建操作,从而大大降低了代码之间的耦合度。这种低耦合的代码结构使得程序在后续的维护、扩展等方面更加方便,提高了代码的可维护性和可扩展性。
(3)代理模式
代理模式是一种设计模式,在该模式中,通过 ProxyUser 类来代理 AdminUser 类与 NormalUser 类所具备的各种业务方法。具体而言,ProxyUser 类承担起了中间代理的职责,它会拦截对 AdminUser 和 NormalUser 业务方法的访问请求。在这个过程中,代理模式的一个重要功能就是实现权限校验。权限校验是一个关键的环节,它能够对发起操作的角色进行严格的权限检查。通过这种检查机制,能够切实确保不同角色的用户只能执行与他们自身所拥有的对应权限相匹配的操作。也就是说,具有管理员角色的用户只能执行管理员权限范围内的操作,普通用户也只能执行普通用户权限允许的操作,以此保证系统操作的安全性和规范性。
(五)系统架构设计
系统采用分层架构设计,从上至下分为入口层、代理层、业务层、数据层、工具层和常量层,各层职责明确,层次清晰:
1.入口层
在整个程序的架构体系中,LibrarySystem类承担着程序入口的重要职责。它主要的功能是接收用户从外部输入的各种信息,并且实现角色选择这一关键功能。当用户启动程序后,LibrarySystem类会等待用户输入相关信息,然后根据用户的输入引导用户进行角色的选择,从而为后续不同角色的操作奠定基础。
2.物理层
ProxyUser类在系统中发挥着至关重要的作用,它主要承担着权限控制与业务分发的双重任务。在系统运行过程中,当有用户发起操作请求时,ProxyUser类会首先对用户的权限进行严格验证。只有在验证通过后,它才会根据用户的请求和其对应的角色,调用相应业务层的方法来处理具体的业务,以此确保系统操作的安全性和业务处理的准确性。
3.业务层
业务层主要由AdminUser类和NormalUser类组成。其中,AdminUser类负责实现管理员相关的业务功能,它封装了管理员角色在系统中所涉及的核心业务逻辑,比如对系统整体的管理和维护等操作。而NormalUser类则专注于实现普通用户的业务功能,它将普通用户在系统中能够进行的各种操作的核心逻辑进行了封装,例如普通的查询、借阅等操作。
4.数据层
数据层主要由Library类和Book类构成。Library类在系统中负责对图书数据进行全面的管理,涵盖了添加新图书、更新已有图书信息、删除不需要的图书以及查询特定图书等一系列操作。通过这些操作,确保了图书数据的完整性和准确性。而Book类作为图书的实体类,它将图书相关的各种属性(如书名、作者、出版日期等)以及与图书相关的方法(如获取图书信息、设置图书信息等)进行了封装,方便对图书进行统一的管理和操作。
5.工具层
工具层主要体现在utils包中的各个工具类上,例如ScannerSingleton、LibrarySingleton、AnalyzingBook等。这些工具类为系统提供了一系列通用的工具方法,包括输入功能,方便用户与系统进行交互;图书管理功能,协助对图书数据进行更好的组织和维护;数据解析功能,能够对系统中涉及的数据进行有效的解析和处理。这些工具类的存在,提高了系统开发和维护的效率。
6.常量层
常量层主要由Constant类来实现,它的主要作用是定义系统配置相关的各种常量。这些常量包括图书数组的默认容量,它规定了系统在初始状态下能够容纳的图书数量;文件路径,明确了系统中相关文件的存储位置;操作指令常量,为系统中的各种操作提供了统一的指令标识。通过定义这些常量,使得系统在维护过程中更加方便,当需要对系统配置进行修改时,只需要在Constant类中进行修改即可。
(六)模块划分
系统基于Java项目的src目录结构进行模块划分,按功能职责将代码分类存放,具体目录结构如下:
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| src/ ├─ book/ // 图书相关(Book、PairOfUidAndBookId) ├─ constant/ // 常量定义(Constant) ├─ user/ // 用户相关 │ ├─ factory/ // 工厂类 │ ├─ AdminUser.java │ ├─ NormalUser.java │ └─ User.java ├─ utils/ // 工具类 │ ├─ ScannerSingleton.java │ ├─ LibrarySingleton.java │ └─ AnalyzingBook.java └─ LibrarySystem.java // 程序入口 └─ PersistentBookManagementSystem.java //界面实现 | |
(七)界面设计
1. 界面架构设计
为了进一步完善系统架构,我们决定增加「界面层」,并将其巧妙地嵌入到原有的分层架构之中。这样一来,便形成了一个「入口层→界面层→代理层→业务层→数据层」的完整流程。此完整流程就如同一条精密的生产线,每个环节都紧密相连、各司其职,共同保障系统的稳定运行。下面为你详细阐述各层的具体职责:
界面层:这一层主要承担着图形化组件的渲染工作。它就像是一位技艺精湛的画师,将各种图形元素精心绘制在屏幕上,为用户呈现出美观、直观的界面。同时,界面层还负责接收用户的交互事件,例如按钮点击、输入框输入等。这些交互事件就像是用户与系统沟通的桥梁,界面层能够敏锐地捕捉到用户的每一个操作,为后续的功能实现提供基础。
对接逻辑:需要特别注意的是,界面层并不会直接对数据进行操作。这是为了确保业务逻辑的统一,避免出现混乱和错误。界面层通过调用代理层(ProxyUser)或业务层(AdminUser/NormalUser)的方法来实现具体的功能。代理层和业务层就像是界面层的得力助手,它们拥有处理各种业务逻辑的能力,能够根据界面层传递过来的用户需求,准确地完成相应的任务。这样的设计使得系统的各个层次分工明确、协作有序,提高了系统的可维护性和可扩展性。
2.界面模块划分
表3-2 界面模块划分
|-----------|----------|--------------------------------------------|
| 界面模块 | 对应功能模块 | 核心组件 |
| 登录与角色选择界面 | 入口层角色选择 | 输入框(用户名/用户ID)、单选按钮(角色选择)、登录/退出按钮 |
| 管理员主界面 | 管理员功能模块 | 功能按钮区(图书上架/更新/下架等)、图书列表表格、统计图表弹窗、新增/修改图书弹窗 |
| 普通用户主界面 | 普通用户功能模块 | 搜索框、图书列表表格、借阅/归还按钮、个人借阅记录表格、到期提醒标签 |
| 异常提示界面 | 异常处理模块 | 弹窗(提示输入错误、库存不足、文件读写失败等)、重试/关闭按钮 |
该表梳理了图书管理系统的界面模块与功能模块的对应关系及核心组件:登录与角色选择界面作为入口层支撑角色选择,核心组件包含用户名 / ID 输入框、角色单选按钮及登录 / 退出按钮;管理员主界面承载管理员功能模块,涵盖图书操作功能按钮区、图书列表表格、统计图表弹窗及图书增改弹窗;普通用户主界面适配普通用户功能模块,包含搜索框、图书列表、借阅 / 归还按钮、个人借阅记录表格及到期提醒标签;异常提示界面服务于异常处理模块,核心为各类异常提示弹窗及重试 / 关闭按钮。
四、系统详细设计与实现
(一)核心类设计
1. User类体系设计
User类为抽象父类,封装所有用户的共性属性(姓名、用户ID、角色),并定义抽象方法display(显示操作菜单),供子类实现。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public abstract class User { protected String name; protected int userID; protected String role; public User(String name, int userID, String role) { this.name = name; this.userID = userID; this.role = role; } public abstract int display(); // 显示操作菜单 } |
2. AdminUser类设计
AdminUser类继承自User类,实现管理员专属业务逻辑,核心方法包括图书上架、更新、下架等。
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class AdminUser extends User { public AdminUser(String name, int userID, String role) { super(name, userID, role); } @Override public int display() { System.out.println("=====管理员操作菜单====="); System.out.println("1. 图书上架"); System.out.println("2. 图书更新"); System.out.println("3. 图书下架"); System.out.println("4. 借阅统计"); System.out.println("5. 热门图书查询"); System.out.println("6. 库存管理"); System.out.println("7. 图书查找"); System.out.println("8. 显示所有图书"); System.out.println("9. 退出系统"); System.out.println("======================"); System.out.print("请输入操作指令:"); return ScannerSingleton.getInstance().nextInt(); } // 图书上架方法 public void addBook(Book book) { Library library = LibrarySingleton.getInstance(); library.addBook(book); System.out.println("图书上架成功!"); } // 其他管理员专属方法(图书更新、下架等)省略... } |
3. NormalUser类设计
NormalUser类继承自User类,实现普通用户专属业务逻辑,核心方法包括图书借阅、归还等。
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class NormalUser extends User { public NormalUser(String name, int userID, String role) { super(name, userID, role); } @Override public int display() { System.out.println("=====普通用户操作菜单====="); System.out.println("1. 图书借阅"); System.out.println("2. 图书归还"); System.out.println("3. 个人借阅记录查询"); System.out.println("4. 图书搜索"); System.out.println("5. 图书查找"); System.out.println("6. 显示所有图书"); System.out.println("7. 退出系统"); System.out.println("========================"); System.out.print("请输入操作指令:"); return ScannerSingleton.getInstance().nextInt(); } // 图书借阅方法 public void borrowBook(int bookId) { Library library = LibrarySingleton.getInstance(); Book book = library.findBookById(bookId); if (book != null && book.getStock() > 0) { // 记录借阅信息并更新库存 library.recordBorrow(this.userID, bookId); book.setStock(book.getStock() - 1); System.out.println("图书借阅成功!借阅期限为30天,请按时归还。"); } else { System.out.println("图书不存在或库存不足,借阅失败!"); } } // 其他普通用户专属方法(图书归还、借阅记录查询等)省略... } |
4. Book类设计
Book类作为图书实体,封装图书ID、名称、作者、出版社、上架时间、库存等属性,并提供getter和setter方法。
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class Book { private int bookId; private String name; private String author; private String publisher; private LocalDate shelfTime; private int stock; public Book(int bookId, String name, String author, String publisher, LocalDate shelfTime, int stock) { this.bookId = bookId; this.name = name; this.author = author; this.publisher = publisher; this.shelfTime = shelfTime; this.stock = stock; } // getter和setter方法省略... } |
5. 设计模式实现类
( 1 ) 单例模式实现:ScannerSingleton类确保输入工具唯一实例。
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ScannerSingleton { private static Scanner instance; private ScannerSingleton() {} public static Scanner getInstance() { if (instance == null) { instance = new Scanner(System.in); } return instance; } } |
( 2 ) 工厂模式实现:AdminUserFactory类负责创建管理员对象。
|----------------------------------------------------------------------------------------------------------------------------------------------|
| public class AdminUserFactory { public static User createAdminUser(String name, int userID) { return new AdminUser(name, userID, "管理员"); } } |
( 3 ) 代理模式实现:ProxyUser类代理用户业务方法,进行权限校验。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ProxyUser { private User user; public ProxyUser(User user) { this.user = user; } public void doOperation(int operation) { if (user instanceof AdminUser) { // 管理员权限校验与业务分发 switch (operation) { case 1: // 调用AdminUser的addBook方法 break; // 其他管理员操作省略... } } else if (user instanceof NormalUser) { // 普通用户权限校验与业务分发 switch (operation) { case 1: // 调用NormalUser的borrowBook方法 break; // 其他普通用户操作省略... } } } } |
(二)数据持久化实现
该系统借助 FileUtils.jar 这一工具类来达成文件的读写操作。具体而言,系统会利用这个工具类的相关功能,对文件进行准确无误的读取和写入操作。在数据存储方面,系统会把图书数据和借阅记录分别妥善地存储在特定的文件当中。其中,所有的图书数据会被存储在名为 allbook.txt 的文件里,该文件专门用于存放系统内全部图书的详细信息,包括书名、作者、出版社等;而借阅记录则会被存储在名为 borrowedbook.txt 的文件中,这个文件会记录每一本被借阅图书的相关信息,比如借阅人、借阅时间、归还时间等,以此来实现对图书借阅情况的有效管理和记录。
1. 图书数据存储
将Library中的图书列表序列化为JSON字符串,写入allbook.txt文件。
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public void saveBooksToFile() { List<Book> books = LibrarySingleton.getInstance().getBooks(); String json = JSON.toJSONString(books); try { FileUtils.writeStringToFile(new File(Constant.BOOK_FILE_PATH), json, "UTF-8"); } catch (IOException e) { System.out.println("图书数据存储失败:" + e.getMessage()); } } |
2. 图书数据读取
从allbook.txt文件中读取JSON字符串,反序列化为Book列表,加载到系统中。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public void loadBooksFromFile() { File file = new File(Constant.BOOK_FILE_PATH); if (file.exists()) { try { String json = FileUtils.readFileToString(file, "UTF-8"); List<Book> books = JSON.parseArray(json, Book.class); LibrarySingleton.getInstance().setBooks(books); } catch (IOException e) { System.out.println("图书数据加载失败:" + e.getMessage()); } } } |
(三)核心功能实现流程
1. 图书上架流程
(1)具体步骤
1)管理员录入图书相关信息(ID、名称、作者等)。
2)系统生成Book对象,并调用AdminUser的addBook方法。
3)Library类获取Book对象,将其添加至图书列表。
4)调用数据持久化方法,将更新后的图书列表保存到文件中。
(2)功能流程
图4-1展示了"图书上架"功能的时序图,全面描述了管理员发起图书上架请求后的具体操作流程:管理员首先发出请求,ProxyUser负责验证其管理员身份;身份验证通过后,AdminUser指导管理员录入图书信息,接着创建Book对象并调用Library的addBook()方法;Library对库存进行检查并将图书添加至列表,随后调用AnalyzingBook的storeBook()方法,将数据写入allbook.txt文件;最终,文件返回存储结果,依次经由Library、AdminUser、ProxyUser传递,向管理员反馈"图书上架成功"。整个过程体现了各模块(ProxyUser权限校验、AdminUser业务处理、Library数据管理、AnalyzingBook文件操作)之间的协作逻辑,实现了图书上架的权限控制、数据处理与持久化闭环。

图4-1核心功能时序图(以图书上架为例)
2. 图书借阅流程
(1)普通用户通过系统界面的输入框填写目标图书的唯一标识ID,点击"借阅"按钮后,系统自动调用NormalUser类中封装的borrowBook方法,该方法会接收用户输入的图书ID作为核心参数,并触发后续的借阅流程校验逻辑。
(2)系统首先通过图书ID在全量图书数据列表中执行精确匹配查询,验证该图书是否存在于系统数据库中;若图书存在,则进一步读取其库存字段数值,判断当前可借阅的库存数量是否大于0,以此确保借阅操作的可行性。
(3)当图书存在且库存充足的校验条件均满足后,系统会自动将该图书的库存数量减1以完成库存更新操作,同时在借阅记录数据表中新增一条完整的借阅信息,该信息包含借阅用户的唯一ID、所借图书的ID以及系统当前时间戳对应的借阅时间。
(4)系统调用封装好的数据持久化工具类中的save方法,将新增的借阅记录同步写入借阅记录文件,并将更新后的图书库存数据覆盖写入全量图书信息文件,确保所有操作数据被永久保存,避免程序重启后数据丢失。
(四)界面详细实现
1 . 核心界面实现代码示例
(1)登录界面核心代码(对接用户工厂模式)
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| private void showLoginDialog() { JDialog loginDialog = new JDialog(); loginDialog.setTitle("用户登录"); loginDialog.setSize(350, 250); loginDialog.setLocationRelativeTo(null); loginDialog.setModal(true); loginDialog.setUndecorated(true); loginDialog.setShape(new RoundRectangle2D.Double(0, 0, 350, 250, 15, 15)); JPanel panel = new JPanel(); panel.setBackground(Color.WHITE); panel.setBorder(new EmptyBorder(20, 20, 20, 20)); panel.setLayout(new GridLayout(4, 2, 10, 15)); JTextField userField = new JTextField(); JComboBox<String> typeBox = new JComboBox<>(new String[]{"管理员", "普通用户"}); JButton loginBtn = createStyledButton("登录", new Color(100, 150, 255)); JButton cancelBtn = createStyledButton("退出", new Color(200, 200, 200)); panel.add(new JLabel("用户名:")); panel.add(userField); panel.add(new JLabel("用户类型:")); panel.add(typeBox); panel.add(new JLabel());panel.add(new JLabel()); panel.add(loginBtn);panel.add(cancelBtn); loginDialog.add(panel); // 核心登录逻辑 loginBtn.addActionListener(e -> { String userName = userField.getText().trim(); if (userName.isEmpty()) {showTipDialog("用户名不能为空!", false);return;} User user = UserFactory.createUser((String) typeBox.getSelectedItem(), userName); if (user == null) {showTipDialog("用户类型非法!", false);return;} currentUserName = user.getUserName(); currentUserType = user.getUserType(); loginDialog.dispose();initMainFrame(); }); cancelBtn.addActionListener(e -> System.exit(0)); loginDialog.setVisible(true);} // 工厂模式核心interface User { String getUserName(); String getUserType();}class AdminUser implements User { private final String userName; public AdminUser(String userName) {this.userName = userName;} @Override public String getUserName() {return userName;} @Override public String getUserType() {return "admin";}}class NormalUser implements User { private final String userName; public NormalUser(String userName) {this.userName = userName;} @Override public String getUserName() {return userName;} @Override public String getUserType() {return "user";}}class UserFactory { public static User createUser(String type, String name) { return switch (type) { case "管理员" -> new AdminUser(name); case "普通用户" -> new NormalUser(name); default -> null; }; }} |
(2)管理员主界面图书上架功能对接(调用原有业务方法)
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| private void initMainFrame() { mainFrame = new JFrame("图书管理系统 - 当前用户:" + currentUserName + (currentUserType.equals("admin") ? "(管理员)" : "(普通用户)")); mainFrame.setSize(900, 650); mainFrame.setLocationRelativeTo(null); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.getContentPane().setBackground(new Color(245, 247, 250)); mainFrame.setLayout(new BorderLayout(10, 10)); // 顶部功能栏 functionPanel = new JPanel(); functionPanel.setBackground(new Color(245, 247, 250)); functionPanel.setBorder(new EmptyBorder(15, 20, 10, 20)); functionPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 15, 0)); // 管理员专属按钮 if (currentUserType.equals("admin")) { functionPanel.add(createStyledButton("图书上架", new Color(70, 200, 120))); functionPanel.add(createStyledButton("删除图书", new Color(255, 100, 100))); functionPanel.add(createStyledButton("查看借阅记录", new Color(150, 100, 255))); } // 公共按钮 functionPanel.add(createStyledButton("借阅图书", new Color(255, 150, 70))); functionPanel.add(createStyledButton("归还图书", new Color(100, 200, 200))); functionPanel.add(createStyledButton("刷新列表", new Color(180, 180, 180))); mainFrame.add(functionPanel, BorderLayout.NORTH); refreshTable(); // 表格初始化} |
(3)图书上架弹窗(输入图书信息并调用业务方法)
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| private void showAddBookDialog() { JDialog addDialog = new JDialog(mainFrame, "图书上架", true); addDialog.setSize(400, 350); addDialog.setLocationRelativeTo(mainFrame); addDialog.setUndecorated(true); addDialog.setShape(new RoundRectangle2D.Double(0, 0, 400, 350, 15, 15)); JPanel panel = new JPanel(); panel.setBackground(Color.WHITE); panel.setBorder(new EmptyBorder(20, 20, 20, 20)); panel.setLayout(new GridLayout(5, 2, 10, 15)); JTextField idField = new JTextField(); JTextField nameField = new JTextField(); JTextField authorField = new JTextField(); JTextField stockField = new JTextField(); JButton confirmBtn = createStyledButton("确认上架", new Color(70, 200, 120)); JButton cancelBtn = createStyledButton("取消", new Color(200, 200, 200)); panel.add(new JLabel("图书ID:"));panel.add(idField); panel.add(new JLabel("书名:"));panel.add(nameField); panel.add(new JLabel("作者:"));panel.add(authorField); panel.add(new JLabel("库存数量:"));panel.add(stockField); panel.add(confirmBtn);panel.add(cancelBtn); addDialog.add(panel); confirmBtn.addActionListener(e -> { try { String bookId = idField.getText().trim(); String bookName = nameField.getText().trim(); String author = authorField.getText().trim(); int stock = Integer.parseInt(stockField.getText().trim()); if (bookId.isEmpty() || bookName.isEmpty() || author.isEmpty() || stock <= 0) { showTipDialog("请输入合法信息!库存需为正整数", false); return; } if (getBookById(bookId) != null) { showTipDialog("图书ID已存在!", false); return; } addBookToSystem(bookId, bookName, author, stock); showTipDialog("《" + bookName + "》上架成功!", true); addDialog.dispose(); refreshTable(); } catch (NumberFormatException ex) { showTipDialog("库存必须是有效数字!", false); } });} |
2 . 核心界面与业务逻辑对接流程
以「图书上架」为例,阐述界面层与原有业务层、数据层的对接流程:
(1)管理员在主界面点击「图书上架」按钮,触发弹窗显示;
(2)用户于弹窗中填写图书信息,并点击「确认上架」按钮;
(3)弹窗捕获输入内容,生成Book对象;
(4)调用AdminUser.addBook()方法(原有的业务逻辑);
(5)AdminUser借助LibrarySingleton调用Library.addBook(),将图书信息加入内存列表;
(6)调用Library.saveBooksToFile()方法,将数据存储至allbook.txt文件;
(7)表格模型(BookTableModel)获取新增图书信息,刷新界面表格展示;
(8)弹窗显示「上架成功」提示,流程至此完成。
五、系统测试
(一)测试目的及概述
系统测试的核心目标,从本质上来说,就是要细致且全面地验证各个功能模块是否严格符合预先设定的需求设计。这一验证过程至关重要,因为只有通过严谨的验证,才能切实确保整个系统能够稳定、准确地运行。这里的稳定运行意味着系统在长时间的使用过程中不会出现频繁的故障或崩溃,能够持续为用户提供可靠的服务;而准确运行则要求系统能够按照设计要求精确地处理各种输入信息,并输出符合预期的结果。
测试的范围相当广泛,它全面涵盖了管理员与普通用户所涉及的所有功能模块。对于这些功能模块的测试,涉及到多个关键方面。首先是功能正确性,这要求每个功能模块都能够按照设计意图正常工作,实现预期的业务逻辑。例如,在一个电商系统中,商品的添加、删除、修改等功能都必须准确无误地执行。其次是权限控制有效性,系统需要严格区分不同用户的权限,确保管理员和普通用户只能访问和操作他们被授权的功能和数据。比如,管理员可以进行系统设置和用户管理,而普通用户只能进行商品浏览和下单等操作。再者是数据持久化可靠性,系统要保证在各种情况下,如系统崩溃、网络中断等,数据都能够被安全地保存和恢复,不会出现数据丢失或损坏的情况。最后是异常处理能力,当系统遇到各种异常情况,如输入错误、网络故障等时,能够及时、有效地进行处理,避免系统出现不可预料的错误或崩溃。
为了确保测试结果的真实性与有效性,测试环境需要与系统开发环境保持一致。这是因为在相同的环境下进行测试,能够最大程度地模拟系统在实际运行中的情况,从而发现和解决可能出现的问题。如果测试环境与开发环境存在差异,可能会导致一些在开发环境中未被发现的问题在实际运行中暴露出来,给系统的稳定性和可靠性带来潜在风险。因此,保持测试环境与开发环境的一致性是系统测试中不可或缺的重要环节。
(二)系统功能模块测试
1. 管理员功能测试
表5-1 管理员功能测试表
|------|-------------------------------------------|----------------------|------|
| 测试用例 | 测试步骤 | 预期结果 | 测试结果 |
| 图书上架 | 1. 管理员登录系统;2. 选择"图书上架"功能;3. 输入合法图书信息 | 图书成功添加到系统,文件中存储该图书数据 | 通过 |
| 图书更新 | 1. 管理员选择"图书更新"功能;2. 输入存在的图书ID;3. 输入新的图书信息 | 图书信息更新成功,文件中数据同步更新 | 通过 |
| 图书下架 | 1. 管理员选择"图书下架"功能;2. 输入存在的图书ID | 图书从系统中删除,文件中数据同步删除 | 通过 |
| 借阅统计 | 1. 系统存在多条借阅记录;2. 管理员选择"借阅统计"功能 | 显示总借阅次数、各图书借阅次数等统计信息 | 通过 |
该完整的测试用例表全面且细致地验证了图书管理系统管理员端的4个核心功能。这4个核心功能涵盖了图书管理流程中的关键环节,具体包括图书上架功能,此功能要求在合法信息录入之后,将图书数据成功入库并且持久化到文件当中,以确保数据的稳定存储和后续可查;图书更新功能,其作用是当存量图书的ID信息需要修改时,能够实现系统与文件之间的信息同步更新,保证数据的一致性;图书下架功能,在存量图书ID被删除之后,系统会自动与文件数据进行同步移除操作,避免残留无效数据;借阅统计功能,当系统中存在借阅记录时,会清晰展示总借阅次数以及单本图书的借阅次数,为管理员提供详细的借阅数据参考。在整个测试过程中,所有功能均严格按照预先设定的测试步骤逐一完成验证工作。经过严谨的测试,测试结果均显示为通过,这表明图书管理系统管理员端的核心业务逻辑与持久化效果均符合最初的设计预期,能够稳定、准确地运行。
2. 普通用户功能测试
表5-2 普通用户功能测试表
|--------|---------------------------------|-----------------------------|------|
| 测试用例 | 测试步骤 | 预期结果 | 测试结果 |
| 图书借阅 | 1. 普通用户登录;2. 输入存在且有库存的图书ID | 借阅成功,图书库存减少,借阅记录保存 | 通过 |
| 图书归还 | 1. 普通用户输入已借阅的图书ID;2. 选择"图书归还"功能 | 归还成功,图书库存增加,借阅记录更新 | 通过 |
| 借阅记录查询 | 1. 普通用户有历史借阅记录;2. 选择"个人借阅记录查询" | 显示该用户所有借阅记录(图书信息、借阅时间、归还状态) | 通过 |
| 权限控制 | 普通用户尝试执行图书上架操作 | 系统提示无权限,操作失败 | 通过 |
此测试用例表主要针对图书管理系统的普通用户端所具备的核心功能以及权限控制方面开展全面验证工作。具体而言,它涵盖了以下四类关键场景。其一为图书借阅场景:普通用户在成功登录系统之后,能够对有库存的图书发起借阅操作,在完成借阅流程后,系统会相应地减少该图书的库存数量,并且会准确无误地保存相关的借阅记录。其二是图书归还场景:当用户归还之前已经借阅的图书时,系统会自动增加该图书的库存数量,同时对相关的借阅记录进行及时更新,以保证数据的实时性和准确性。其三是借阅记录查询场景:该功能可以展示出用户历史上所借阅的图书的具体信息,包括图书的名称、作者等,同时还会显示借阅时间以及当前的归还状态,方便用户随时了解自己的借阅情况。其四是权限控制场景:若普通用户尝试进行图书上架操作,系统会立即提示用户无此权限,并且该操作会以失败告终,从而确保系统的操作权限得到严格管控。目前,所有测试步骤均已顺利完成验证工作,且验证结果均显示为通过。这充分确认了普通用户端的核心业务逻辑运行正常,同时权限管控措施切实生效,保障了系统的安全性和稳定性。
(三)异常处理测试
表5-3 异常处理测试表
|--------|------------------------|---------------------|------|
| 测试用例 | 测试步骤 | 预期结果 | 测试结果 |
| 输入非法数据 | 借阅图书时输入非数字的图书ID | 系统提示输入格式错误,要求重新输入 | 通过 |
| 文件读写异常 | 手动删除allbook.txt文件后启动系统 | 系统提示数据加载失败,初始化空图书列表 | 通过 |
| 库存不足借阅 | 普通用户借阅库存为0的图书 | 系统提示库存不足,借阅失败 | 通过 |
该测试用例表主要是针对图书管理系统在各种异常场景下的情况展开全面验证。具体来说,它涵盖了以下三类异常场景。其一为输入非法数据的情况,例如在进行借阅操作时,如果输入的图书 ID 并非数字形式,系统就会提示格式错误,以此来检验系统对输入数据格式的严格把控能力。其二是文件读写异常的场景,当删除系统中的核心数据文件之后再启动系统,系统会提示加载失败,并且会将相关数据初始化为空列表,这可以验证系统在文件读写出现问题时的应对机制。其三是库存不足借阅的情形,若尝试借阅库存数量为 0 的图书,系统会明确提示库存不足,同时借阅操作会失败,这能考察系统对库存状态的准确判断和处理能力。在整个测试过程中,所有预先设定的测试步骤都已经完成了详细的验证工作,并且验证的结果均为通过。由此可以确认,图书管理系统的异常处理逻辑是符合最初预期的,能够在不同的异常状况下做出正确且合理的响应。
六、总结与展望
(一)项目总结
本项目以Java技术栈为核心,成功设计并实现了一套功能完整的图书管理系统,全面达成预设的研究目标与业务需求。系统采用分层架构设计,整合Java基础语法与单例、工厂、代理三种设计模式,明确划分管理员与普通用户权限边界,覆盖图书管理全流程核心功能,并通过文件读写机制实现数据持久化存储。
开发过程中,设计模式的工程价值得到充分验证:单例模式避免资源重复消耗,工厂模式降低代码耦合度,代理模式保障权限控制严谨性。团队同步掌握Java项目从框架搭建、模块划分、核心类设计到功能实现与测试的全流程开发方法,代码设计与工程化能力显著提升。
系统测试结果显示,各功能模块运行稳定且符合需求,权限控制精准,数据持久化机制可靠,可满足图书管理场景实际应用需求。项目创新实现图形化界面与业务逻辑无缝对接,开发登录、管理员、普通用户三类界面,替代传统命令行交互方式,大幅优化用户操作体验。
界面层采用模块化设计,与系统分层架构高度适配,未影响原有代码可维护性与扩展性。通过表格、弹窗、图表等可视化组件优化数据展示形式,使图书信息、借阅记录及统计结果呈现更清晰直观。
(二)不足与展望
1. 项目不足
(1)交互方式单一,当前仅支持传统的命令行文本交互模式,用户需通过输入特定指令字符完成操作,全程依赖文字指令输入与输出,操作流程对非技术背景用户不够友好,整体用户体验存在较大提升空间。
(2)数据存储采用纯文本文件格式(如TXT文件),未使用MySQL、SQLite等结构化数据库进行数据管理,在图书信息条目超过千条、用户查询操作频繁(如高峰时段并发检索)的场景下,文本文件的逐行读取、写入与检索方式会导致数据处理效率显著降低,无法满足大规模数据的高效管理需求。
(3)功能模块覆盖不够完善,核心业务流程中缺少用户注册(含身份验证)、图书预约(支持未来时间段预留)、逾期提醒(自动计算超期天数并推送通知)等高频实用功能,难以匹配图书馆日常运营中的实际业务场景需求。
(4)现有界面仅支持按钮、文本框等基础Swing组件,视觉样式较为简单朴素,缺乏皮肤定制(允许用户切换主题风格)、响应式布局(适配不同屏幕分辨率)等交互优化;未来可引入JavaFX框架替代传统Swing,利用其丰富的UI控件库与CSS样式支持,实现更现代、美观且交互流畅的界面设计;进一步扩展界面功能维度,如添加图书封面上传(支持JPG/PNG格式图片存储)、扫码借阅(集成ZXing库实现二维码识别)、移动端适配(通过WebView组件嵌入H5页面)等创新功能,全面提升系统的实用性与用户体验。
2. 未来展望
(1)借助Java Swing或者JavaFX这两种强大的技术,精心构建出具有良好交互性的图形化用户界面。通过对界面元素的合理布局、操作流程的细致优化,改良整个操作流程,让用户在使用过程中能够更加便捷、高效地完成各项任务,从而显著增强用户在使用系统时的整体体验。
(2)将MySQL数据库深度融合到系统当中,用其取代传统的文本文件来进行数据存储。MySQL数据库具有强大的数据管理能力和高效的查询机制,这样做能够极大地提升数据查询与操作的效率。无论是简单的数据检索还是复杂的数据处理,都能在更短的时间内完成,进而助力系统对更大数据量进行有效的管理。
(3)对系统的功能进行全面拓宽,有针对性地增添一系列实用的功能。比如增加用户注册功能,方便新用户加入系统;添加图书预约功能,让用户能够提前预订心仪的图书;引入逾期罚款计算功能,规范图书借阅的归还时间;强化图书分类管理功能,使图书的管理更加有序。通过这些功能的增加,显著提高系统的实用性,满足用户多样化的需求。
(4)对代码架构进行深入改进,积极引入Spring Boot之类的优秀框架。Spring Boot框架具有诸多优势,能够简化开发流程、提高开发效率。通过引入该框架,进一步提高系统的可扩展性与可维护性,使得系统在面对功能的增加和需求的变化时能够更加灵活地应对。同时,支持Web化部署,让系统可以在网络环境中方便地访问,达成多终端访问的目标,用户可以通过不同的设备随时随地使用系统。
附录
(一)核心代码文件清单
|-------------------|-------------------------|--------------------------|
| 文件路径 | 文件名称 | 功能描述 |
| src/book/ | Book.java | 图书实体类,封装图书属性与方法 |
| src/book/ | PairOfUidAndBookId.java | 封装用户ID与图书ID的关联类,用于借阅记录管理 |
| src/constant/ | Constant.java | 定义系统常量(文件路径、操作指令等) |
| src/user/ | AdminUser.java | 管理员业务实现类 |
| src/user/ | NormalUser.java | 普通用户业务实现类 |
| src/user/ | User.java | 用户抽象父类 |
| src/user/factory/ | AdminUserFactory.java | 管理员对象创建工厂类 |
| src/user/factory/ | NormalUserFactory.java | 普通用户对象创建工厂类 |
| src/utils/ | ScannerSingleton.java | 输入工具单例类 |
| src/utils/ | LibrarySingleton.java | 图书管理核心单例类 |
| src/utils/ | AnalyzingBook.java | 图书数据解析工具类 |
| src/ | LibrarySystem.java | 程序入口类,负责角色选择与系统启动 |
(二)系统运行截图(示例)
1.系统启动与角色选择界面


2、管理员操作菜单界面


3、图书上架功能运行界面


4、普通用户图书借阅功能运行界面

5、数据文件存储示例(allbook.txt内容)
