当前位置: 首页 > news >正文

Java实战:从零开发图书管理系统

在这里插入图片描述

🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:【Java】内容概括

在这里插入图片描述
在这里插入图片描述
【前言】

在学习 JavaSE 的过程中,通过实战项目来巩固知识是非常有效的方式。图书管理系统是一个经典的小型项目,它涵盖了Java 面向对象编程、异常处理等多个核心知识点。通过开发这个系统,我们能将零散的知识整合起来,深入理解 Java 程序的设计与开发流程。

文章目录:

  • 一、思维导图
  • 二、模块设计
  • 三、user模块
  • 二、book模块
  • 五、library模块
  • 六、utils模块
  • 七、ProxyUser模块
  • 七、 业务具体实现
    • 1.查找图书,显示图书,退出系统
    • 2. 管理员检查权限
    • 3.管理员上架图书
    • 4.管理员更新图书
    • 5.管理员下架图书
    • 6.管理员统计每本书的借阅次数
    • 7.管理员查询最受欢迎的前n 本书
    • 8.管理员查看库存状态
    • 9.管理员移除上架超过⼀年的图书
    • 10.普通用户检查权限
    • 11. 普通用户借阅图书
    • 12. 普通用户归还图书
    • 13. 普通用户查看当前个人借阅情况
  • 八、 LibrarySystem类

一、思维导图

通过思维导图可以更好的理解整个图书系统
在这里插入图片描述

二、模块设计

在图书系统中,先设计四大模块:用户,书籍,工具,常量值

在这里插入图片描述

三、user模块

在图书管理系统中,用户分为管理员普通用户(不止一个哦),但他们都有这些属性:姓名,ID,角色

  • User

public abstract class User {private String name;private int userID;private String role;//用户角色public User(String name, int userID, String role) {this.name = name;this.userID = userID;this.role = role;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getUserID() {return userID;}public void setUserID(int userID) {this.userID = userID;}public String getRole() {return role;}public void setRole(String role) {this.role = role;}/**** @return返回具体选择了什么操作* 1 2 3 4 ...*/public abstract int display();@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", userID=" + userID +", role='" + role + '\'' +'}';}
}
  • AdminUser

public class AdminUser extends User{public Scanner scanner;public Library library;public AdminUser(String name, int userID) {super(name, userID, "管理员");scanner = ScannerSingleton.getScannerSingleton();library = Library.getLibrary();}@Overridepublic int display() {System.out.println(" 管理员 " + this.getName() + " 的操作菜单:");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. 查看最后欢迎的前 K 本书 ");System.out.println("9. 查看库存状态 ");System.out.println("10. 检查超过⼀年未下架的图书 ");System.out.println(" 请选择你的操作: ");return scanner.nextInt();}//其他操作⽅法具体实现...
  • NormalUser
public class NormalUser extends User {public Scanner scanner;public Library library;//存储图书借阅信息private PairOfUidAndBookId[] pairOfUidAndBookIds;//当前图书借阅量private int borrowedCount;private final AnalyzingBorrowedBook analyzingBorrowedBook = new AnalyzingBorrowedBook();public NormalUser(String name, int userID) {super(name, userID, "普通用户");loadBorrowedBook();scanner = ScannerSingleton.getScannerSingleton();library = Library.getLibrary();}private void loadBorrowedBook() {PairOfUidAndBookId[] allBorrowedBook;//加载文件借阅信息try {allBorrowedBook = analyzingBorrowedBook.loadObject(Constant.BORROWED_BOOK_MAX_NUM);//默认已借阅图书数组大小为BORROW_BOOK_MAX_NUMpairOfUidAndBookIds = new PairOfUidAndBookId[Constant.BORROW_BOOK_MAX_NUM];//没有读取到已借阅图书if (allBorrowedBook == null) {borrowedCount = 0;} else {//实际数组长度int allBorrowedBookLen = allBorrowedBook.length;//读取超出范围if (allBorrowedBookLen > pairOfUidAndBookIds.length) {//重新分配内存pairOfUidAndBookIds = new PairOfUidAndBookId[allBorrowedBookLen];}//拷贝到已借阅图书数组中for (int i = 0; i < allBorrowedBookLen; i++) {pairOfUidAndBookIds[i] = allBorrowedBook[i];//更新数据borrowedCount = allBorrowedBookLen;}}} catch (IOException e) {throw new RuntimeException(e);}}private void storeBorrowBook() {try {analyzingBorrowedBook.storyObject(pairOfUidAndBookIds, Constant.BORROWED_BOOK_MAX_NUM);} catch (IOException e) {throw new RuntimeException(e);}}@Overridepublic int display() {System.out.println(" 用户 " + this.getName() + " 的操作菜单:");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(" 请选择你的操作: ");return scanner.nextInt();}
//其他操作⽅法具体实现...
  • ProxyUser

public class ProxyUser {private User realUser;private Library library;public  ProxyUser(User user){this.realUser = user;library = Library.getLibrary();}public int display(){return this.realUser.display();}public int getRealUser() {return this.realUser.display();}//管理员相关方法//普通用户相关方法}

二、book模块

  • Book:存放书籍各种属性
    在这里插入图片描述

public class Book implements Comparable<Book>{//书idprivate int bookId;//书名private String title;//作者private String author;//类别private String category;//出版年份private int publishYearl;//借阅状态private boolean isBorrowed;//借阅次数private int borrowCount;//上架时间private LocalDate ShelfDate;//构造方法,初始化图书对象,id,借阅状态,次数不用传参public Book(String title, String author, String category, int publishYearl, LocalDate shelfDate) {this.title = title;this.author = author;this.category = category;this.publishYearl = publishYearl;ShelfDate = shelfDate;}public int getBookId() {return bookId;}public void setBookId(int bookId) {this.bookId = bookId;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getCategory() {return category;}public void setCategory(String category) {this.category = category;}public int getPublishYearl() {return publishYearl;}public void setPublishYearl(int publishYearl) {this.publishYearl = publishYearl;}public boolean isBorrowed() {return isBorrowed;}public void setBorrowed(boolean borrowed) {isBorrowed = borrowed;}public int getBorrowCount() {return borrowCount;}public void setBorrowCount(int borrowCount) {this.borrowCount = borrowCount;}public LocalDate getShelfDate() {return ShelfDate;}public void setShelfDate(LocalDate shelfDate) {ShelfDate = shelfDate;}//对借阅次数 每次自增1 自减1public void incrementBorrowCount() {this.borrowCount++;}public void decreaseBorrowCount() {this.borrowCount--;}@Overridepublic String toString() {return "Book{" +"bookId=" + bookId +", title='" + title + '\'' +", author='" + author + '\'' +", category='" + category + '\'' +", publishYearl=" + publishYearl +", isBorrowed=" + isBorrowed +", borrowCount=" + borrowCount +", ShelfDate=" + ShelfDate +'}';}

将书籍信息拼接成JSON格式的字符串

  public String toJSON(){StringBuilder json = new StringBuilder();json.append(bookId).append(",");json.append(title).append(",");json.append(author).append(",");json.append(category).append(",");json.append(borrowCount).append(",");json.append(isBorrowed).append(",");json.append(borrowCount).append(",");json.append( ShelfDate!= null ? ShelfDate.format(DateTimeFormatter.ISO_LOCAL_DATE) : "null");return json.toString();}

对后期对象的比较做准备

 @Overridepublic int compareTo(Book o) {return o.getBorrowCount()-this.getBorrowCount();}
}

五、library模块

  • Library类
    初始化数组容量,可以放在常量值包中
    在这里插入图片描述

public class Library {//存储的书籍public Book[] books;//记录当前有效书籍public int bookCount;private static Library library;public Scanner scanner = new Scanner(System.in);private AnalyzingBook analyzingBook = new AnalyzingBook();private Library(){//调用该构造方法时,要加载文件当中的数据到books数组当中//读loadAllBook();}public static Library getLibrary(){if (library == null){library = new Library();}return library;}//写成独立的方法,方便后面实时更新private void loadAllBook() {//读取文件书籍到allBook数组中try {Book[] allBook = analyzingBook.loadObject(Constant.ALL_BOOK_FILE_NAME);// 给当前书架默认分配大小为5books = new Book[Constant.CAPACIYY];if (allBook == null){bookCount = 0;}else {int allBookLen = allBook.length;//5if (allBookLen > books.length){books = new Book[allBookLen];}for (int i = 0; i < allBookLen; i++) {books[i] = allBook[i];}//有效书籍bookCount = allBookLen;}} catch (IOException e) {throw new RuntimeException(e);}}

存储图书到⽂件中

  private void storeBook() {try {analyzingBook.storeObject(books,Constant.ALL_BOOK_FILE_NAME);} catch (IOException e) {throw new RuntimeException(e);}}

存储所有图书的文件放在常量值包中
在这里插入图片描述

六、utils模块

  • AnalyzingBook类
  • 实现文件内容的读取

  • 先将书籍数组对象中每个书籍对象进行字符串的序列号,也就是Book类中的toJSON方法
    在这里插入图片描述

  • 每本书籍之间使用“\n”进行分割

  • 把对应书籍组装成书籍对象

public class AnalyzingBook {public void storeObject(Book[] books,String filename) throws IOException {//有效书籍int booksUseLen = 0;for (int i = 0; i < books.length; i++) {if (books[i] != null) {booksUseLen++;}}//使每个属性使用逗号拼接StringBuilder jsonArray = new StringBuilder();for (int i = 0; i < booksUseLen; i++) {if (books[i] != null) {jsonArray.append(books[i].toJSON());if (i != booksUseLen - 1) {jsonArray.append("\n");}}}//把内存中存储的数据写到磁盘上FileUtils.writeFile(jsonArray.toString(),filename);}//从文件读取数据public Book[] loadObject(String filename) throws IOException{//从磁盘的文件中读取数据String content = FileUtils.readFile(filename);if (content == null ||content.isEmpty()){System.out.println("图书馆为空");return null;}//用\n作为分隔符进行字符串分隔String[] bookJsonStrings = content.split("\n");//把对应的字符串“组装”成书籍对象Book[] bookList = new Book[bookJsonStrings.length];for (int i = 0; i < bookJsonStrings.length; i++) {Book book = parseBookJson(bookJsonStrings[i]);bookList[i] = book;}return bookList;}

parseBookJson方法

  • 检查json是否为空
  • 使用逗号分隔每个属性的值
  • 每个属性进行转化赋值
  • 构造书籍对象
 //“0,java,baby...”private Book parseBookJson(String json){String[] pairs = json.split(",");int bookId = Integer.parseInt(pairs[0]);String title = pairs[1];String author = pairs[2];String category = pairs[3];int publishYear = Integer.parseInt(pairs[4]);boolean isBorrowed = Boolean.parseBoolean(pairs[5]);int borrowCount = Integer.parseInt(pairs[6]);LocalDate shelfDate = LocalDate.parse(pairs[7]);if (title != null && author != null && category != null && shelfDate !=null) {Book book = new Book(title, author, category, publishYear, shelfDate);book.setBorrowed(isBorrowed);book.setBorrowCount(borrowCount);book.setBookId(bookId);return book;}return null;}//测试public static void main(String[] args) {Book[] books = new Book[4];books[0] = new Book("java", "baby", " 编程 ", 1994, LocalDate.of(2023, 9, 24));books[1] = new Book("mysql", "lisi", " 编程 ", 1999, LocalDate.of(2024, 2, 10));books[2] = new Book("php", "baby", " 编程 ", 2020, LocalDate.of(2023, 9, 23));books[3] = new Book("西游记", " 吴承恩 ", "⼩说 ", 2024, LocalDate.of(2023, 9, 23));AnalyzingBook analyzingBook = new AnalyzingBook();//Alt+Entertry {analyzingBook.storeObject(books,"Constant.ALL_BOOK_FILE_NAME");//将数据读到ret数组里面Book[] ret = analyzingBook.loadObject("Constant.ALL_BOOK_FILE_NAME");for (int i = 0; i < ret.length; i++) {System.out.println(ret[i]);}} catch (IOException e) {throw new RuntimeException(e);}}
}

七、ProxyUser模块

  • 判断代理对象是否具有权限
  • 调用对应用户的方法进行操作
  • 查找图书,显示图书,退出系统这三个功能两种用户都具备,写在Library中,不需要区分
public class ProxyUser {private User realUser;private Library library;public  ProxyUser(User user){this.realUser = user;library = Library.getLibrary();}public int display(){return this.realUser.display();}public int getRealUser() {return this.realUser.display();}//管理员相关方法//用户相关方法}

七、 业务具体实现

在这里插入图片描述

1.查找图书,显示图书,退出系统

这三个功能两种用户都具备,写在Library中,不需要区分。
使用常量代替case的判断条件,并定义在Constant中
在这里插入图片描述

 public void handleOperation(int choice) {if(this.realUser instanceof AdminUser){switch (choice){case Constant.SEARCH_BOOK:library.searchBook();break;case Constant.DISPLAY_BOOK:library.displayBook();break;case Constant.EXIT:library.exit();break;case Constant.ADD_BOOK:addBook();break;case Constant.UPDATE_BOOK:updateBook();break;case Constant.REMOVE_BOOK:removeBook();break;case Constant.BORROWED_BOOK_COUNT:borrowCount();break;case Constant.GENERATE_BOOK:generateBook();break;case Constant.CHECK_INVENTORY_STATUS:checkInventoryStatus();break;case Constant.CHECK_AND_REMOVE_OLD_BOOK:checkAndRemoveOldBooks();break;default:System.out.println("⽆效的操作。 ");}}else if (realUser instanceof NormalUser) {//普通⽤⼾操作switch (choice) {case Constant.SEARCH_BOOK:library.searchBook();break;case Constant.DISPLAY_BOOK:library.displayBook();break;case Constant.EXIT:library.exit();case Constant.BORROWED_BOOK:borrowBook();break;case Constant.RETURN_BOOK:returnBook();break;case Constant.VIEW_BORROW_HISTORY_BOOK:viewBorrowHistory();break;default:System.out.println("⽆效的操作。 ");}}}

2. 管理员检查权限

  • ProxyUser类
 private void checkRealUserWhetherAdminUser(String msg){if(!(this.realUser instanceof AdminUser)){throw new PermissionException(msg);}}

3.管理员上架图书

  • ProxyUser类
 //上架图书public void addBook() {System.out.println("代理类addBook方法执行了");try {checkRealUserWhetherAdminUser("普通用户没有权限添加书籍");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).addBook();}
  • AdminUser类
 //上架图书public void addBook() {System.out.println("Admin类addBook方法执行了");scanner.nextLine();//防止有其他字符影响输入System.out.println(" 请输⼊书名: ");String title = scanner.nextLine();  //输⼊书名System.out.println(" 请输⼊作者: ");String author = scanner.nextLine();  //输⼊作者System.out.println(" 请输⼊类别: ");String category = scanner.nextLine();  //输⼊图书类别System.out.println(" 请输⼊出版年份: ");int year = scanner.nextInt();  //输⼊出版年份LocalDate shelfDate = LocalDate.now();Book book = new Book(title,author,category,year,shelfDate);library.addBook(book);}
  • Library类
 public void addBook(Book book) {System.out.println("Library类addBook执行了");if (bookCount >= books.length) {System.out.println("图书馆已满,无法上架图书");return;}books[bookCount] = book;Book bookLast = books[bookCount-1];book.setBookId(bookLast.getBookId()-1);storeBook();System.out.println("图书上架成功,名称为:" + book.getTitle());}

4.管理员更新图书

  • ProxyUser类
 //图书修改⽀持修改书名作者类别public void updateBook() {try {checkRealUserWhetherAdminUser("普通用户没有权限更新书籍");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).updateBook();}
  • AdminUser类
//图书修改⽀持修改书名作者类别public void updateBook() {//展示所有书籍library.displayBook();System.out.println("请输入你要修改的id:");int bookId = scanner.nextInt();scanner.nextLine();Book book = library.searchById(bookId);if (book == null){System.out.println("没有你要找的这本ID的书:"+bookId);return;}System.out.println(" 当前书名:" + book.getTitle());System.out.println(" 请输⼊新的书名:");String newTitle = scanner.nextLine();  //输⼊新的书名System.out.println(" 当前作者: " + book.getAuthor());System.out.println(" 请输⼊新的作者: ");String newAuthor = scanner.nextLine();  //输⼊新的作者System.out.println(" 当前类别: " + book.getCategory());System.out.println(" 请输⼊新的类别: ");String newCategory = scanner.nextLine();  //输⼊新的类别book.setTitle(newTitle);book.setAuthor(newAuthor);book.setCategory(newCategory);library.updateBook(book);}
  • Library类
//通过bookId找到对应书籍,没=没有就返回nullpublic Book searchById(int bookId) {loadAllBook();//最新的图书for (int i = 0; i < bookCount; i++) {Book book = books[i];if (book.getBookId() == bookId) {return book;}}return null;}public void updateBook(Book book) {int bookId = book.getBookId();int index = searchByIdReturnIndex(book.getBookId());books[index] = book;if(index == -1){System.out.println("没有你要更新的图书,此时Id为:"+bookId);return;}books[index] = book;storeBook();//更新数据System.out.println("书籍已被更新,文件已被写入,更新之后书籍为:");System.out.println(books[index]);}private int searchByIdReturnIndex(int bookId) {loadAllBook();for (int i = 0; i < bookCount; i++) {Book book = books[i];if (book.getBookId() == bookId){return i;}}return -1;}

5.管理员下架图书

  • ProxyUser类
 //删除书籍public void removeBook() {try {checkRealUserWhetherAdminUser("普通用户没有权限删除书籍");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).removeBook();}
  • AdminUser类
 //删除书籍public void removeBook() {library.displayBook();System.out.println("请输入");int bookId = scanner.nextInt();scanner.nextLine();Book removeBook = library.searchById(bookId);if (removeBook == null){System.out.println("没有你要删除的图书");return;}library.removeBook(bookId);System.out.println(" 图书: "+removeBook.getTitle()+" 已经被删除! ");}
  • Library类
 public void updateBook(Book book) {int bookId = book.getBookId();int index = searchByIdReturnIndex(book.getBookId());books[index] = book;if(index == -1){System.out.println("没有你要更新的图书,此时Id为:"+bookId);return;}books[index] = book;storeBook();//更新数据System.out.println("书籍已被更新,文件已被写入,更新之后书籍为:");System.out.println(books[index]);}

6.管理员统计每本书的借阅次数

  • ProxyUser类
 //统计每本书的借阅次数public void borrowCount() {try {checkRealUserWhetherAdminUser("普通用户没有权限查看图书借阅次数");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).borrowCount();}
  • AdminUser类
//统计每本书的借阅次数public void borrowCount() {library.borrowCount();}
  • Library类
 public void borrowCount() {loadAllBook();for (int i = 0; i < bookCount; i++) {Book book = books[i];System.out.println(" 书名:"+book.getTitle()+ " 借阅次数: "+book.getBorrowCount());}}

7.管理员查询最受欢迎的前n 本书

  • ProxyUser类
//查询最受欢迎的前n 本书public void generateBook() {try {checkRealUserWhetherAdminUser("普通用户没有权限查询最受欢迎的前n 本书");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).generateBook();}
  • AdminUser类
//查询最受欢迎的前k 本书public void generateBook() {System.out.println(" 请输⼊你要查看的最受欢迎的前 K 本书 , 注意 k 值不能超 过: "+library.bookCount);int k = scanner.nextInt();if(k<= 0 || k>library.bookCount ){System.out.println("没有最受欢迎的前"+k+"本书");return;}library.generateBook(k);}
  • Library类
 public void generateBook(int k) {loadAllBook();//把所有书籍放在临时数组,进行排序Book[] tmp = new Book[bookCount];for (int i = 0; i < bookCount; i++) {tmp[i] = books[i];}//开始排序Arrays.sort(tmp);//把前k本书拷贝到新数组Book[] generateBooks = new Book[k];for (int i = 0; i < k; i++) {generateBooks[i] = tmp[i];}//打印新数组System.out.println("最受欢迎书籍:");for (int i = 0; i < generateBooks.length; i++) {Book book = generateBooks[i];System.out.println(" ID: "+book.getBookId()+" 书名: "+ book.getTitle()+" 作者: "+ book.getAuthor()+" 借阅次数: "+book.getBorrowCount());}}

8.管理员查看库存状态

  • ProxyUser类
 //查看库存状态public void checkInventoryStatus() {try {checkRealUserWhetherAdminUser("普通用户没有权限查看库存状态");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).checkInventoryStatus();}
  • AdminUser类
//查看库存状态public void checkInventoryStatus() {library.checkInventoryStatus();}
  • Library类
 public void checkInventoryStatus() {loadAllBook();for (int i = 0; i < bookCount; i++) {Book book = books[i];String status = "未借出";if(book.isBorrowed()){status  = "已借出";}System.out.println(" 书名: "+book.getTitle()+"⽬前状态: "+status);}}

9.管理员移除上架超过⼀年的图书

  • ProxyUser类
//并移除上架超过⼀年的图书public void checkAndRemoveOldBooks() {try {checkRealUserWhetherAdminUser("普通用户没有权限移除上架超过⼀年的图书");}catch (PermissionException e){e.printStackTrace();}((AdminUser)(this.realUser)).checkAndRemoveOldBooks();}
  • AdminUser类
//并移除上架超过⼀年的图书public void checkAndRemoveOldBooks(){library.checkAndRemoveOldBooks();}
  • Library类
 public void checkAndRemoveOldBooks() {//移除上架超过⼀年的图书loadAllBook();//获取当前时间戳long currentTimestamp = System.currentTimeMillis();//将当前时间戳转换为LocalDateLocalDate currentDate = Instant.ofEpochMilli(currentTimestamp).atZone(ZoneId.systemDefault()).toLocalDate();boolean flg = false;for (int i = 0; i < bookCount; i++) {Book book = books[i];//获取当前书籍的上架时间LocalDate specifiedDate = book.getShelfDate();//计算两个⽇期之间的差值(以年为单位)long yearsBetween = ChronoUnit.YEARS.between(specifiedDate,currentDate);if(yearsBetween >= 1) {System.out.print(" 图书 " + book.getTitle() + " 已经上架超过⼀年,是否 移除? (y/n): ");scanner.nextLine();String response = scanner.nextLine();if (response.equalsIgnoreCase("y")) {//确认删除调⽤remove⽅法进⾏删除removeBook(book.getBookId());i--;  //因为后⾯的书已经向前移动,所以要重新检查当前索引位置}flg = true;}}if(!flg) {System.out.println(" 没有上架超过⼀年的图书! ");}storeBook();}

10.普通用户检查权限

  • ProxyUser类
private void checkRealUserWhetherNormalUser(String msg) {if(!(realUser instanceof NormalUser)){throw new PermissionException(msg);}}

11. 普通用户借阅图书

  • ProxyUser类
//借阅图书public void borrowBook(){System.out.println("代理类borrowBook方法执行了");checkRealUserWhetherNormalUser("管理员不能借阅图书,请换做普通用户来借阅");((NormalUser)(this.realUser)).borrowBook();}
  • NormalUser类
//借阅图书public void borrowBook() {scanner.nextLine();System.out.println("请输入你要借阅的图书id:");int bookId = scanner.nextInt();scanner.nextLine();//如果书架没有书 不能借阅if (library.bookCount == 0) {System.out.println("书架没有书籍暂时不能借阅");return;}//加载已借阅的图书信息loadBorrowedBook();//判断要借阅的书 是否存在Book book = library.searchById(bookId);if (book == null) {System.out.println("没有该id相关书籍:" + bookId);return;}//开始准备借阅图书for (int i = 0; i < borrowedCount; i++) {PairOfUidAndBookId pairOfUidAndBookIds1 = pairOfUidAndBookIds[i];if (pairOfUidAndBookIds1.getBookId() == book.getBookId()) {//getUserID当前用户IDif (pairOfUidAndBookIds1.getBookId() == getUserID()) {System.out.println("这本书自己已经借阅过");return;} else {System.out.println("这本书别人已经借阅过");return;}}}library.boorowBook(bookId);//写入借阅书籍的txtPairOfUidAndBookId pairOfUidAndBookId = new PairOfUidAndBookId(getUserID(), book.getBookId());pairOfUidAndBookIds[borrowedCount%4] = pairOfUidAndBookId;borrowedCount++;storeBorrowBook();System.out.println("借阅书籍成功");}
  • Library类
 public void boorowBook(int bookId) {loadAllBook();Book book = searchById(bookId);book.setBorrowed(true);book.incrementBorrowCount();storeBook();}

12. 普通用户归还图书

  • ProxyUser类
    //归还图书public void returnBook(){System.out.println("代理类returnBook方法执行了");checkRealUserWhetherNormalUser("管理员不能归还图书,请换做普通用户来归还");((NormalUser)(this.realUser)).returnBook();}
  • NormalUser类
  //归还图书public void returnBook(){loadBorrowedBook();if (borrowedCount == 0){System.out.println("目前没有用户借阅过书籍");return;}scanner.nextLine();System.out.println("请输入你要归还的书籍ID:");int bookId = scanner.nextInt();scanner.nextLine();//判断要借阅的书 是否已经被自己借阅过了Book book = library.searchById(bookId);if (book == null){System.out.println("没有该Id相关的书籍:"+bookId);return;}for (int i = 0; i < borrowedCount; i++) {//判断书的ID是否相同if(pairOfUidAndBookIds[i].getBookId() == book.getBookId()){//判断用户IDif(getUserID() == pairOfUidAndBookIds[i].getUserId()){library.returnBook(bookId);System.out.println("图书'" +book.getTitle()+"'已成功归还");//用最后一本书替换归还掉的书pairOfUidAndBookIds[i] = pairOfUidAndBookIds[borrowedCount-1];//清空最后一个pairOfUidAndBookIds[borrowedCount - 1] = null;borrowedCount--;storeBorrowBook();}else {System.out.println("该图书不是你借阅的,无法归还:"+book.getTitle());}return;}}}
  • Library类
 public void returnBook(int bookId) {loadAllBook();Book book = searchById(bookId);book.setBorrowed(false);book.decreaseBorrowCount();storeBook();}

13. 普通用户查看当前个人借阅情况

  • ProxyUser类
 //查看当前个人借阅情况public void viewBorrowHistory(){System.out.println("代理类viewBorrowHistory方法执行了");checkRealUserWhetherNormalUser("管理员不能查看图书,请换做普通用户来查看");((NormalUser)(this.realUser)).viewBorrowHistory();}
  • NormalUser类
 //查看当前个人借阅情况public void viewBorrowHistory(){loadBorrowedBook();System.out.println("借阅情况如下:");if(borrowedCount == 0){System.out.println("目前没有借阅记录");}else {boolean flg = false;for (int i = 0; i < borrowedCount; i++) {//用户id相同时,查看书籍idif(pairOfUidAndBookIds[i].getBookId() == getUserID()){flg = true;Book book = library.searchById(pairOfUidAndBookIds[i].getBookId());System.out.println(book);}}if (!flg){System.out.println("你没有借阅过书籍");}}}

八、 LibrarySystem类

运用的工厂,代理模式,可以参考这篇详解:【Java】设计模式——单例、工厂、代理模式

public class LibrarySystem {public static void main(String[] args) {//工厂模式IUserFactory adminUserFactory = new AdminUserFactory();User adminUser = adminUserFactory.creatUser(" 王先生 ", 1);IUserFactory normalUserFactory = new NormalUserFactory();User normal1 = normalUserFactory.creatUser(" 小白 ", 2);User normal2 = normalUserFactory.creatUser("小飞 ", 3);//代理模式ProxyUser proxyUserAdmin = new ProxyUser(adminUser);ProxyUser proxyUserNormal1 = new ProxyUser(normal1);ProxyUser proxyUserNormal2 = new ProxyUser(normal2);

这里的proxyUserAdminproxyUserNormal1proxyUserNormal2代理对象,要根据用户的选择,来确定对象

        LibrarySystem librarySystem = new LibrarySystem();ProxyUser currentUser = librarySystem.selectProxyRole(proxyUserAdmin,proxyUserNormal1,proxyUserNormal2);while (true){int choice = currentUser.display();//选择choice就执行这个用户的某个操作currentUser.handleOperation(choice);}}
    public ProxyUser selectProxyRole(ProxyUser proxyUserAdmin, ProxyUser proxyUsernormal1, ProxyUser proxyUsernormal2) {System.out.println("选择角色进行登录:");System.out.println("1. 管理员\n2.普通⽤⼾(小白)\n3.普通⽤⼾(小⻜)\n4.退出系统 ");ProxyUser currentUser = null;Scanner scanner = new Scanner(System.in);int choice = scanner.nextInt();switch (choice) {case 1:currentUser = proxyUserAdmin;break;case 2:currentUser = proxyUsernormal1;break;case 3:currentUser = proxyUsernormal2;break;case 4:System.exit(0);System.out.println("退出系统了");break;default:break;}return currentUser;}
}

项目执行结果
在这里插入图片描述

【总结】

通过图书管理系统的开发,我对 JavaSE 的核心知识点有了更深入的理解:

  • 熟练运用面向对象思想(封装、继承、多态)进行类设计。

  • 理解单例模式、代理模式等设计模式在实际项目中的应用。

  • 提升了调试能力,能快速定位并解决空指针、数组越界等常见异常。 这个项目不仅巩固了JavaSE 知识,也让我体会到软件开发的完整流程,从需求分析、模块设计到编码实现、调试优化,每一步都需要严谨的思考与实践。

在这里插入图片描述


文章转载自:

http://QjjDFqjU.gpzjr.cn
http://jS1Y5zbg.gpzjr.cn
http://hzHuslPY.gpzjr.cn
http://sVkOPtrb.gpzjr.cn
http://GHpmUcP7.gpzjr.cn
http://XYlDh5fx.gpzjr.cn
http://GjBdM7lQ.gpzjr.cn
http://HZv6o2RK.gpzjr.cn
http://alx0SbLa.gpzjr.cn
http://nxiYWFmN.gpzjr.cn
http://cQVQ9Lgp.gpzjr.cn
http://5IADCuiU.gpzjr.cn
http://5bceYpWc.gpzjr.cn
http://bAaU5Xds.gpzjr.cn
http://YTYd45dP.gpzjr.cn
http://Rm9iYm4h.gpzjr.cn
http://wunm5yAg.gpzjr.cn
http://llHAGhAv.gpzjr.cn
http://smXz3wuc.gpzjr.cn
http://mmvx0zDO.gpzjr.cn
http://Uup86RQz.gpzjr.cn
http://21ifUD72.gpzjr.cn
http://El4S19rU.gpzjr.cn
http://JTMcR2GQ.gpzjr.cn
http://flj32ZB3.gpzjr.cn
http://YG2RdqeL.gpzjr.cn
http://rvq0zzGt.gpzjr.cn
http://VQaFV7ry.gpzjr.cn
http://ECqVFkTi.gpzjr.cn
http://eesTcCwu.gpzjr.cn
http://www.dtcms.com/a/384403.html

相关文章:

  • 认知语义学中的隐喻对人工智能自然语言处理的深层语义分析的启示与影响研究报告
  • Mysql数据库事务全解析:概念、操作与隔离级别
  • Halcon 常用算子
  • 基于Spring Boot与Micrometer的系统参数监控指南
  • 【高并发内存池——项目】定长内存池——开胃小菜
  • 作为注册中心zk和nacos如何选型
  • 前置配置3:nacos 配置中心
  • Linux —— 进程的程序替换[进程控制]
  • [Linux] 从YT8531SH出发看Linux网络PHY驱动
  • ArcGIS定向影像(2)——非传统影像轻量级解决方案
  • 分享机械键盘MCU解决方案
  • Unity 性能优化 之 编辑器创建资源优化(UGUI | 物理 | 动画)
  • PostgreSQL——分区表
  • Elastic APM 高级特性:分布式追踪与机器学习优化
  • Ubuntu 服务器配置转发网络访问
  • Redis 数据结构源码剖析(SDS、Dict、Skiplist、Quicklist、Ziplist)
  • C#通讯之网络通讯 TCP UDP
  • 响应时间从5ms到0.8ms:威迈斯AI+DSP协同架构的突破与工程实践
  • 《WINDOWS 环境下32位汇编语言程序设计》第16章 WinSock接口和网络编程(2)
  • 算法--插入排序
  • 领码方案|权限即数据:企业系统中的字段级访问控制架构实战(Ver=1.0)
  • 【面试场景题】支付金融系统与普通业务系统的一些技术和架构上的区别
  • 数证杯顺心借JAVA网站重构详细版(服务器取证基础考点+检材+题目+重构视频)
  • 【Unity】【Photon】Fusion2中的玩家输入系统 学习笔记
  • Vue3 + Three.js 实战:自定义 3D 模型加载与交互全流程
  • 【Leetcode hot 100】102.二叉树的层序遍历
  • [Windows] 微软 .Net 运行库离线安装包 | Microsoft .Net Packages AIO_v09.09.25
  • java通过RESTful API实现两个项目之间相互传输数据
  • C++基础(13)——list类的模拟实现
  • C#/.NET/.NET Core技术前沿周刊 | 第 54 期(2025年9.8-9.14)