图书管理系统 - 完整分析和优化
1. 系统整体架构 - 类图
classDiagram
%% 主程序类
class Main {
+login() User
+main(String[] args) void
}
%% 数据类
class Book {
-String name
-String author
-int price
-String type
-boolean borrowed
+Book(String, String, int, String)
+toString() String
}
class BookList {
-Book[] books
-int usedSize
+BookList()
+getBook(int) Book
+setBook(int, Book) void
+getUsedSize() int
+setUsedSize(int) void
}
%% 用户类
class User {
#String name
#Ioperation[] ioperations
+User(String)
+abstract menu() int
+doOperation(int, BookList) void
}
class NormalUser {
+NormalUser(String)
+menu() int
}
class AdminUser {
+AdminUser(String)
+menu() int
}
%% 操作接口和类
class Ioperation {
<<interface>>
+work(BookList) void
}
class FindOperation
class BorrowOperation
class ReturnOperation
class AddOperation
class DeleteOperation
class ShowOperation
class ExitOperation
%% 关系定义
Main --> User
Main --> BookList
User <|-- NormalUser
User <|-- AdminUser
User --> Ioperation
Ioperation <|.. FindOperation
Ioperation <|.. BorrowOperation
Ioperation <|.. ReturnOperation
Ioperation <|.. AddOperation
Ioperation <|.. DeleteOperation
Ioperation <|.. ShowOperation
Ioperation <|.. ExitOperation
Ioperation --> BookList
BookList o--> Book
2. 主程序执行流程 - 序列图
sequenceDiagram
participant M as Main
participant S as Scanner
participant U as User
participant BL as BookList
participant IO as Ioperation
Note over M: 程序启动
M->>S: 获取用户输入
S-->>M: 用户名和身份
M->>U: 创建用户对象
U-->>M: 返回用户实例
loop 主循环
M->>U: 显示菜单
U-->>M: 返回用户选择
M->>U: 调用doOperation
U->>IO: 执行对应操作
IO->>BL: 操作书籍数据
BL-->>IO: 返回结果
IO-->>M: 操作完成
end
Note over M: 用户选择退出
M->>IO: 执行退出操作
IO-->>M: 系统退出
3. 用户登录流程 - 流程图
graph TD
A[程序启动] --> B[显示欢迎界面]
B --> C[输入用户名]
C --> D{输入用户身份}
D -- 0 --> E[创建普通用户NormalUser]
D -- 1 --> F[创建管理员用户AdminUser]
E --> G[初始化普通用户操作数组]
E --> H[进入普通用户菜单]
F --> I[初始化管理员操作数组]
F --> J[进入管理员菜单]
H --> K[显示普通用户菜单选项]
J --> L[显示管理员菜单选项]
4. 普通用户操作流程 - 状态图
stateDiagram-v2
[*] --> 主菜单
主菜单: 普通用户菜单
主菜单 --> 查找图书: 选择1
主菜单 --> 借阅图书: 选择2
主菜单 --> 归还图书: 选择3
主菜单 --> 退出系统: 选择0
查找图书: 输入书名查找
查找图书 --> 查找结果
查找结果 --> 主菜单
借阅图书: 输入书名借阅
借阅图书 --> 借阅结果
借阅结果 --> 主菜单
归还图书: 输入书名归还
归还图书 --> 归还结果
归还结果 --> 主菜单
退出系统 --> [*]
5. 管理员操作流程 - 活动图
flowchart TD
Start([管理员登录成功]) --> Menu{选择操作}
Menu --> Find[查找图书]
Find --> InputName1[输入书名]
InputName1 --> Search1[搜索图书]
Search1 --> Result1{是否找到?}
Result1 -->|是| Show1[显示图书信息]
Result1 -->|否| NotFound1[提示未找到]
Show1 --> Menu
NotFound1 --> Menu
Menu --> Add[新增图书]
Add --> InputInfo[输入图书信息<br>书名,作者,价格,类型]
InputInfo --> CheckFull[检查书柜是否已满]
CheckFull -->|已满| Full[提示书柜已满]
CheckFull -->|未满| AddBook[添加图书到书柜]
AddBook --> Success1[添加成功提示]
Full --> Menu
Success1 --> Menu
Menu --> Delete[删除图书]
Delete --> InputName2[输入要删除的书名]
InputName2 --> Search2[搜索图书]
Search2 --> Result2{是否找到?}
Result2 -->|否| NotFound2[提示未找到]
Result2 -->|是| Confirm{确认删除?}
Confirm -->|是| DeleteBook[执行删除操作]
DeleteBook --> Success2[删除成功提示]
Confirm -->|否| Cancel[取消删除]
Cancel --> Menu
NotFound2 --> Menu
Success2 --> Menu
Menu --> Show[显示所有图书]
Show --> Traverse[遍历书柜]
Traverse --> Display[显示每本书信息]
Display --> Menu
Menu --> Exit[退出系统]
Exit --> End([程序结束])
6. 借阅/归还操作详细流程 - 序列图
sequenceDiagram
participant User as 用户
participant Menu as 菜单系统
participant Operation as 操作类
participant BookList as 图书列表
participant Book as 图书对象
User->>Menu: 选择借阅/归还功能
Menu->>Operation: 创建对应操作对象
alt 借阅流程
Operation->>User: 提示输入书名
User->>Operation: 输入书名
Operation->>BookList: 遍历查找图书
BookList-->>Operation: 返回图书对象
Operation->>Book: 检查借阅状态
Book-->>Operation: 返回借阅状态
alt 已借出
Operation->>User: 提示"已被借出"
else 未借出
Operation->>Book: 设置借阅状态为true
Operation->>User: 提示"借阅成功"
end
else 归还流程
Operation->>User: 提示输入书名
User->>Operation: 输入书名
Operation->>BookList: 遍历查找图书
BookList-->>Operation: 返回图书对象
Operation->>Book: 检查借阅状态
alt 已借出
Operation->>Book: 设置借阅状态为false
Operation->>User: 提示"归还成功"
else 未借出
Operation->>User: 提示"未借出此书"
end
end
Operation-->>User: 操作完成返回主菜单
7. 系统数据结构关系 - ER图
erDiagram
USER ||--o{ OPERATION : has
USER {
string name
array operations
}
BOOK-LIST ||--o{ BOOK : contains
BOOK-LIST {
array books
int usedSize
}
BOOK {
string name PK
string author
int price
string type
boolean borrowed
}
OPERATION {
int id
string type
}
代码问题分析和优化建议
发现的问题:
-
Main类中main方法错误:
static void main(String[] args) // 错误:缺少public
// 应该改为:
public static void main(String[] args) -
Book类中变量名拼写错误:
private boolean brorrow; // 错误:拼写错误
// 应该改为:
private boolean borrowed; -
BorrowOperation中的逻辑错误:
if(book.getBrorrow()){
System.out.println("这本书已被借出");
}
book.setBrorrow(true); // 错误:无论是否借出都会设置为true
优化版本代码:
// 修复后的BorrowOperation
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements Ioperation {
public void work(BookList booklist) {
System.out.println("=== 借阅图书 ===");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要借阅的图书名称:");
String name = scanner.nextLine();
int cursize = booklist.getUsedSize();
for (int i = 0; i < cursize; i++) {
Book book = booklist.getBook(i);
if (book.getName().equals(name)) {
if (book.isBorrowed()) { // 改为isBorrowed()方法
System.out.println("抱歉,这本书已被借出!");
} else {
book.setBorrowed(true); // 改为setBorrowed()方法
System.out.println("借阅成功!");
}
return;
}
}
System.out.println("抱歉,没有找到《" + name + "》这本书。");
}
}
系统优化建议:
-
添加输入验证:
// 在菜单选择时添加验证
public int menu() {
int choice = -1;
while (true) {
try {
choice = scanner.nextInt();
if (choice >= 0 && choice < ioperations.length) {
break;
} else {
System.out.println("请输入有效的选项(0-" + (ioperations.length-1) + ")");
}
} catch (Exception e) {
System.out.println("请输入数字!");
scanner.next(); // 清除无效输入
}
}
return choice;
} -
添加图书去重检查:
// 在AddOperation中添加检查
private boolean isBookExist(BookList booklist, String name) {
for (int i = 0; i < booklist.getUsedSize(); i++) {
if (booklist.getBook(i).getName().equals(name)) {
return true;
}
}
return false;
} -
增加书柜扩容功能:
// 在BookList中添加扩容方法
public void ensureCapacity(int minCapacity) {
if (minCapacity > books.length) {
Book[] newBooks = new Book[Math.max(books.length * 2, minCapacity)];
System.arraycopy(books, 0, newBooks, 0, books.length);
books = newBooks;
}
}
系统特点总结
-
多态设计:通过User基类和Ioperation接口实现多态
-
策略模式:不同用户有不同的操作策略
-
数据封装:图书信息封装在Book类中
-
职责分离:不同操作类负责不同功能
-
可扩展性:易于添加新的操作和用户类型
这个系统是一个设计良好的Java控制台应用程序,展示了面向对象设计原则的实际应用!📚
java
import book.BookList;
import user.AdminiUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
public class Main {
public static User login() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的名字");
String name = sc.nextLine();
Scanner sc1 = new Scanner(System.in);
System.out.println("请输入你的身份" +
"1为管理员" +
"0为普通用户");
int choice = sc1.nextInt();
if (choice == 0) {
return new NormalUser(name);
} else {
return new AdminiUser(name);
}
}
static void main(String[] args) {
//展示书柜
BookList booklist=new BookList();
User user=login();
while(true){
int choice=user.menu();
user.doIoperation(choice, booklist);
}
}
}
package book;
public class Book {
private String name;
private String author;
private int price;
private String type;
private boolean brorrow;
public Book(String name,String author,int price,String type){
this.name=name;
this.author=author;
this.price=price;
this.type=type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Boolean getBrorrow() {
return brorrow;
}
public void setBrorrow(Boolean brorrow) {
this.brorrow = brorrow;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((brorrow==true)? " 已借出": " 未借出")+
'}';
}
}
package book;
public class BookList {
private Book[] books=new Book[10];
private int usesize;
public BookList() {
this.books[0] = new Book("三国演义","罗贯中",190,"小说");
this.books[1] = new Book("红楼梦","曹雪芹",190,"小说");
this.books[2] = new Book("西游记","吴承恩",190,"小说");
this.usesize=3;
}
/* public Book[] getBook(int pos) {
return books[pos];
}
public void setBook(int pos, Book book) {
this.books[pos] = book;
}
public int getUsesize() {
return usesize;
}
public void setUsesize(int usesize) {
this.usesize = usesize;
}*/
public Book getBook(int pos) {
return books[pos];
}
public void setBook(int pos, Book book) {
this.books[pos] = book;// 重点
}
public int getUsesize() {
return usesize;
}
public void setUsesize(int usesize) {
this.usesize = usesize;
}
public Book[] getBooks() {
return books;
}
}
package ioperations;
import book.BookList;
public interface Ioperation {
public void work(BookList booklist);
}
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class FindOperation implements Ioperation {
public void work(BookList booklist){
System.out.println("查找图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要查找的图书名字");
String name= scanner.nextLine();
int cursize= booklist.getUsesize();
for (int i = 0; i < cursize; i++) {
Book book=booklist.getBook(i);//重点
if(book.getName().equals(name)){
System.out.println("找到这本书");
System.out.println(book);
return;
}
}
System.out.println("没有你要找的书");
// for (int i = 0; i < cursize; i++) {
// Book book = BookList.getBook(i);
// if(book.getName().equals(name)) {
// System.out.println("找到了这本书:");
// System.out.println(book);
// return;
// }
// }
// System.out.println("没有你要找的这本书....");
// }
}
}
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class ReturnOperation implements Ioperation {
public void work(BookList booklist){
System.out.println("归还图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要归还的书名");
String name=scanner.nextLine();
int cursize= booklist.getUsesize();
for (int i = 0; i <cursize ; i++) {
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
if(book.getBrorrow()){
book.setBrorrow(false);
System.out.println("归还成功");
return;
}
}
}
System.out.println("没有你要归还的书");
}
}
package ioperations;
import book.Book;
import book.BookList;
import jdk.dynalink.Operation;
import java.util.Scanner;
public class DeleteOperation implements Ioperation {
public void work(BookList booklist){
System.out.println("删除图书");
System.out.println("请输入你要删除的书的名字");
Scanner scanner=new Scanner(System.in);
String name=scanner.nextLine();
int cursize=booklist.getUsesize();
int i = 0;
int pos=-1;
for (; i < cursize; i++) {
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
pos=i;
break;
}
}
if(pos==cursize){
System.out.println("没有你要删除的书");
return;
}
for (int j = pos; j < cursize-1; j++) {
Book book = booklist.getBook(j);
booklist.setBook(j, book);//Book book是中介
}
booklist.setBook(cursize,null);
booklist.setUsesize(cursize-1);
System.out.println("删除成功");
}
}
package user;
import book.BookList;
import ioperations.Ioperation;
public abstract class User {
protected String name;
public Ioperation[]ioperations;
public User(String name) {
this.name = name;
}
public abstract int menu();
public void doIoperation(int choice, BookList booklist){
ioperations[choice].work(booklist);
}
}
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class BorrowOperation implements Ioperation {
public void work(BookList booklist){
System.out.println("借阅图书");
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要借的书名");
String name=scanner.nextLine();
int cursize=booklist.getUsesize();
for(int i=0;i<cursize;i++){
Book book=booklist.getBook(i);
if(book.getName().equals(name)){
if(book.getBrorrow()){
System.out.println("这本书已被借出");
}
//book.getBrorrow()=ture;错误写法
book.setBrorrow(true);
System.out.println("借阅成功");
return;
}
}
System.out.println("没有你要借阅的书");
}
}
package user;
import ioperations.*;
import java.util.Scanner;
public class AdminiUser extends User {
public AdminiUser(String name) {
super(name);
this.ioperations=new Ioperation[]{
new ExitOPeration(),
new FindOperation(),
new AddOperation(),
new DeleteOperation(),
new ShowOperation()
};
}
public int menu(){
System.out.println("欢迎"+this.name+"来到图书系统");
System.out.println("*******管理员菜单*******");
System.out.println("1. 查找图书");
System.out.println("2. 新增图书");
System.out.println("3. 删除图书");
System.out.println("4. 显示图书");
System.out.println("0. 退出系统");
System.out.println("**********************");
Scanner scanner=new Scanner(System.in);
System.out.println("请进行您的操作");
int choice=scanner.nextInt();
return choice;
}
}
package user;
import ioperations.*;
import java.util.Scanner;
public class NormalUser extends User {
public NormalUser(String name) {
super(name);
this.ioperations=new Ioperation[]{
new ExitOPeration(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
@Override
public int menu() {
System.out.println("欢迎"+this.name+"来到图书系统");
System.out.println("*******普通用户菜单*******");
System.out.println("1. 查找图书");
System.out.println("2. 借阅图书");
System.out.println("3. 归还图书");
System.out.println("0. 退出系统");
System.out.println("**********************");
Scanner scanner=new Scanner(System.in);
int choice=scanner.nextInt();
return choice;
}
}
package ioperations;
import book.Book;
import book.BookList;
public class ShowOperation implements Ioperation{
public void work(BookList booklist){
System.out.println("展示图书");
int cursize= booklist.getUsesize();
for (int i = 0; i < cursize; i++) {
Book book=booklist.getBook(i);
System.out.println(book);
}
}
}
package ioperations;
import book.BookList;
public class ExitOPeration implements Ioperation {
public void work(BookList booklist){
System.out.println("退出系统");
System.exit(0);
}
}