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

图书系统(新)

文章目录

  • 一. 模式
    • (一)单例模式
      • (1)饿汉式单例模式
        • 1. 定义
        • 2. 代码
      • (2)懒汉式单例模式
        • 1. 定义
        • 2. 代码
    • (二)工厂模式
    • (三)代理模式
  • 二. 图书系统框架
    • (一)user
      • (1)Root
      • (2)NormalUser
      • (3)相同方法
      • (4)引入工厂模式
        • 1. IUserFactory
        • 2. RootFactory
        • 3. NormalFactory
      • (5)引入代理模式
    • (二)book
      • (1)Book
      • (2)AnalyzingBook
      • (3)Library
      • (4)BorrowedUidAndBookId
      • (5)AnalyzingBorrowedBook
      • (6)再谈NormalUser
  • 三. 方法实现
    • (一)管理员方法
      • (1)addBook
        • 1. proxyUser中
        • 2. Root中
        • 3. Library中
      • (2)updateBook
        • 1. proxyUser中
        • 2. Root中
        • 3. Library中
      • (3)removeBook
        • 1. proxyUser中
        • 2. Root中
        • 3. Library中
      • (4)borrowCount
        • 1. proxyUser中
        • 2. Root中
        • 3. Library中
      • (5)generateBook
        • 1. proxyUser中
        • 2. Root中
        • 3. Library中
        • 4. Book中
      • (6)checkInventoryStatus
        • 1. ProxyUser中
        • 2. Root中
        • 3. Library中
      • (7)checkAndRemoveOldBooks
        • 1. ProxyUser中
        • 2. Root中
        • 3. Library中
    • (二)普通用户方法
      • (8)borrowBook
        • 1. ProxyUser中
        • 2. NormalUser
        • 3. Library中
      • (9)returnBook
        • 1. proxyUser
        • 2. NormalUser
        • 3. Library中
      • (10)viewBorrowHistory
        • 1. proxyUser
        • 2. NormalUser
    • (三)共同方法
      • (11)searchBook
      • (12)exit
      • (13)displayBooks
      • (14)start
  • 四. 总结

一. 模式

(一)单例模式

一个类有且只有一个实例对象,所以这就需要我们不能在别的类调用单例类的构造方法,于是可以将构造方法私有化,那么该对象只能通过静态方法来获取

(1)饿汉式单例模式

1. 定义

每次程序运行时都实例化一个对象,不管是否用到,先确保该对象是存在的,即饿汉式单例模式

2. 代码
package single;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 18:27*/
public class Singleton {private static Singleton singleton = new Singleton();private Singleton() {}public static Singleton getInstance() {return singleton;}}

(2)懒汉式单例模式

1. 定义

当需要该类对象的时候,通过类主体来调用静态方法获取该对象并且实例化,而不用时则不会实例化该对象

2. 代码
package single;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 18:36*/
public class Singleton_2 {private static Singleton_2 singleton2;private Singleton_2() {}public Singleton_2 getSingleton2() {if (singleton2 == null) {singleton2 = new Singleton_2();return singleton2;}return singleton2;}
}

(二)工厂模式

创建⼀个专⻔负责创建对象的⼯⼚类,将对象的创建过程封装起来,提供一种来创建对象的方式,可以用一个方法创建出多个用户对象,只需要实例化一个工厂类的对象即可,不需要在同时new多个用户,创建对象与使用对象方法分离,实现低耦合

(三)代理模式

代理模式就是通过代理对象来控制对实际对象的访问,起到一个跳转作用

二. 图书系统框架

(一)user

用户User有管理员Root与普通用户NormalUser,所以抽取Root与NormalUser的共同属性与方法,将User定义为抽象类
定义抽象类属性:

  1. String name;(名字)
  2. int ID;(用户id)
  3. String role;(身份)
  4. display()(菜单)
  5. Scanner scanner(输入操作)

(1)Root

root用户对应着管理员的菜单,且role可以写死为**管理员**
package user;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:04*/
public class Root extends User{public Root(String name, int ID) {super(name, ID, "管理员");}@Overridepublic int display() {System.out.println("管理员 " + name + " 的操作菜单:");System.out.println("0. 切换角色");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();}//其他操作⽅法//上架图书public void addBook() {}//图书修改 ⽀持修改书名 作者 类别public void updateBook() {}//删除书籍public void removeBook() {}//统计每本书的借阅次数public void borrowCount() {}//查询最受欢迎的前n本书public void generateBook() {}//查看库存状态public void checkInventoryStatus() {}//并移除上架超过⼀年的图书public void checkAndRemoveOldBooks() {}public void exit() {}
}

(2)NormalUser

NormalUser对应着普通用户的菜单,role可以写死为**普通用户**
package user;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:05*/
public class NormalUser extends User{public NormalUser(String name, int ID) {super(name, ID, "普通用户");}@Overridepublic int display() {System.out.println("普通⽤⼾ " + name + " 的操作菜单:");System.out.println("0. 切换角色");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();}private void loadBorrowedBook() {}private void storeBorrowedBook() {}//借阅图书public void borrowBook() {}//归还图书public void returnBook() {}// 查看个⼈借阅情况public void viewBorrowBooks() {}}

(3)相同方法

通过比较Root与NormalUser的菜单可以发现,其中前四个方法是一样的,而我们所有的方法最后都是要与图书馆进行交互的,所以我们就可以将前四个方法统一定义到图书馆Library
在这里插入图片描述

(4)引入工厂模式

设置一个接口IUserFactory,设置抽象方法,将抽象类User作为返回值参数为name,ID,再设置两个类,RootFactoryNormalFactory实现该接口,RootFactory来实例化Root对象,NormalFactory实例化NormalUser对象

1. IUserFactory
package factory;import user.User;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:40*/
public interface IUserFactory {User createUser(String name, int ID);
}
2. RootFactory
package factory;import user.Root;
import user.User;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:41*/
public class RootFactory implements IUserFactory{@Overridepublic User createUser(String name, int ID) {return new Root(name,ID);}
}
3. NormalFactory
package factory;import user.NormalUser;
import user.User;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:42*/
public class NormalFactory implements IUserFactory{@Overridepublic User createUser(String name, int ID) {return new NormalUser(name,ID);}
}

(5)引入代理模式

将管理员与普通用户的所有方法放入代理类当中,从而实现代理,代理时,根据用户可以根据用户选择身份的不同来接收不同的对象,从而打印选择不同的菜单

package user;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 20:01*/
public class ProxyUser {private User proxyUser;public ProxyUser(User user) {proxyUser = user;}public User getRealUser() {return proxyUser;}}

(二)book

(1)Book

图书系统中必须要有的就是书
书的属性:

  1. private int bookId; //书id
    private String title; // 书名
    private String author; // 作者
    private String category; // 类别
    private int publishYear; // 出版年份
    private boolean isBorrowed; // 借阅状态
    private int borrowCount; // 借阅次数
    private LocalDate shelfDate; // 上架时间
  2. 其中借阅状态,借阅次数默认就是想要的值,且书的ID我们会设置其自增,所以这三个属性都不用初始化,构造方法去掉这三个属性,我们也不希望普通用户来修改书的属性,所以都私有化,同时提供get与set方法,来供root用户修改提供方法
package book;import java.time.LocalDate;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 20:17*/
public class Book {private int bookId; //书idprivate String title; // 书名private String author; // 作者private String category; // 类别private int publishYear; // 出版年份private boolean isBorrowed; // 借阅状态private int borrowCount; // 借阅次数private LocalDate shelfDate; // 上架时间public Book(String title, String author, String category,int publishYear, LocalDate shelfDate) {this.title = title;this.author = author;this.category = category;this.publishYear = publishYear;this.isBorrowed = false;this.borrowCount = 0;this.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 getPublishYear() {return publishYear;}public void setPublishYear(int publishYear) {this.publishYear = publishYear;}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) {this.shelfDate = shelfDate;}@Overridepublic String toString() {return "Book{" +"bookId=" + bookId +", 书名='" + title + '\'' +", 作者='" + author + '\'' +", 类别='" + category + '\'' +", 出版年份=" + publishYear +", 是否借阅=" + isBorrowed +", 借阅次数=" + borrowCount +", 上架时间=" + shelfDate +'}';}
}

(2)AnalyzingBook

希望将每本书都可以永久保存,这需要用到文件,所以需要专门定义一个类来实现读取书写书的功能,同时与图书馆library和图书book交互

package book;import com.bit.utils.FileUtils;import java.time.LocalDate;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 20:37*/
public class AnalyzingBook {/*** 将书写入文件* @param books 书的数组* @param filename 要写入的文件名*/public void writeBook(Book[] books, String filename) {// 先遍历书中有效数据int count = 0;for (int i = 0; i < books.length; i++) {if (books[i] != null) {count++;}}StringBuilder stringBuilder = new StringBuilder();// 将书数组的每本信息都转化为字符串for (int i = 0; i < count; i++) {stringBuilder.append(books[i].toStr());if (i != books.length - 1) {// 除了最后一行,将每行都拼接杀那个一个换行符\nstringBuilder.append("\n");}}FileUtils.writeFile(stringBuilder.toString(),filename);}/*** 从文件中读取书* @param filename 文件名* @return 返回书这个数组*/public Book[] loadBook(String filename) {// 判断目前字符串是否为空if (filename == null || filename.isEmpty()) {return null;}// 从文件中读取字符串String file = FileUtils.readFile(filename);// 将字符串以\n分割成一本本书的信息String[] allBook = file.split("\n");Book[] books = new Book[allBook.length];for (int i = 0; i < allBook.length; i++) {books[i] = toBook(allBook[i]);}return books;}/*** 将每一行信息字符串都转化为书* @param file 每一行的书包含的信息字符串* @return 返回的是一本本书*/public Book toBook(String file) {String[] bookFile = file.split(",");// 每个属性进⾏转化赋值int bookId = Integer.parseInt(bookFile[0]);String title = bookFile[1];String author = bookFile[2];String category = bookFile[3];int publishYear = Integer.parseInt(bookFile[4]);boolean isBorrowed = Boolean.parseBoolean(bookFile[5]);int borrowCount = Integer.parseInt(bookFile[6]);LocalDate shelfDate = LocalDate.parse(bookFile[7]);Book book = new Book(title,author,category,publishYear,shelfDate);// 将其他属性设置成读取到的属性book.setBookId(bookId);book.setBorrowed(isBorrowed);book.setBorrowCount(borrowCount);return book;}
}

(3)Library

图书馆是管理书的类,写书与读取书操作都应该与Library类来交互,所以也要在Library中定义两个交互方法,读书(loadBook)与写书(writeBook)

package book;import constant.Constant;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 21:22*/
public class Library {private Book[] books;private AnalyzingBook analyzingBook = new AnalyzingBook();private int bookCount;private static Library library;public static Library getLibrary() {if (library == null) {return new Library();}return library;}private Library() {loadBook();}/*** 读取书籍*/public void loadBook() {Book[] allBook = analyzingBook.loadBook(Constant.ALL_BOOK);books = new Book[Constant.CAPACITY];if (allBook == null) {bookCount = 0;}else {bookCount = allBook.length;if (bookCount > books.length) {books = new Book[bookCount];}for (int i = 0; i < bookCount; i++) {books[i] = allBook[i];}}}public void writeBook() {analyzingBook.writeBook(books,Constant.ALL_BOOK);}}

(4)BorrowedUidAndBookId

借阅书籍时,要保存书籍的id和用户的id,以及用户名字,与上述book时一个性质

package book;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 22:00*/
public class BorrowedUidAndBookId {private int userID;private int bookID;private String name;public BorrowedUidAndBookId() {}public BorrowedUidAndBookId(int userID, int bookID, String name) {this.userID = userID;this.bookID = bookID;this.name = name;}public int getUserID() {return userID;}public void setUserID(int userID) {this.userID = userID;}public int getBookID() {return bookID;}public void setBookID(int bookID) {this.bookID = bookID;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String toStr() {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(userID).append(",");stringBuilder.append(bookID).append(",");stringBuilder.append(name);return stringBuilder.toString();}
}

(5)AnalyzingBorrowedBook

将借阅id写入到文件中,同时与用户类NormalUser和ID类BorrowedUidAndBookId交互

package book;import com.bit.utils.FileUtils;
import constant.Constant;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 22:05*/
public class AnalyzingBorrowedBook {public void writeID(BorrowedUidAndBookId[] ids, String filename) {// 判断当前数组的真是数据int count = 0;for (int i = 0; i < ids.length; i++) {if (ids[i] != null) {count++;}}StringBuilder stringBuilder = new StringBuilder();for (int i = 0; i < count; i++) {stringBuilder.append(ids[i].toStr());if (i != count - 1) {stringBuilder.append("\n");}}FileUtils.writeFile(stringBuilder.toString(), filename);}public BorrowedUidAndBookId[] loadID(String filename) {String file = FileUtils.readFile(filename);if (file == null || file.isEmpty()) {return null;}String[] id = file.split("\n");BorrowedUidAndBookId[] borrowedUidAndBookIds = new BorrowedUidAndBookId[id.length];for (int i = 0; i < id.length; i++) {borrowedUidAndBookIds[i] = toID(id[i]);}return borrowedUidAndBookIds;}private BorrowedUidAndBookId toID(String file) {String[] id = file.split(",");int userID = Integer.parseInt(id[0]);int bookID = Integer.parseInt(id[1]);String name = id[2];BorrowedUidAndBookId borrowedUidAndBookId = new BorrowedUidAndBookId(userID,bookID,name);return borrowedUidAndBookId;}
}

(6)再谈NormalUser

借阅书籍类BorrowedUidAndBookId与普通用户类NormalUser和工具分析类AnalyzingBorrowedBook交互,所以最终落实到普通用户类

package user;import book.AnalyzingBorrowedBook;
import book.BorrowedUidAndBookId;
import book.Library;
import constant.Constant;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:05*/
public class NormalUser extends User{private BorrowedUidAndBookId[] borrowedIDS;private static AnalyzingBorrowedBook analyzingBorrowedBook = new AnalyzingBorrowedBook();private int borrowedCount;private Library library = Library.getLibrary();public NormalUser(String name, int ID) {super(name, ID, "普通用户");loadBorrowedBook();}@Overridepublic int display() {System.out.println("普通⽤⼾ " + name + " 的操作菜单:");System.out.println("0. 切换角色");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();}private void loadBorrowedBook() {BorrowedUidAndBookId[] ids = analyzingBorrowedBook.loadID(Constant.BORROWED_BOOK_FILE);borrowedIDS = new BorrowedUidAndBookId[Constant.CAPACITY];if (ids == null) {borrowedCount = 0;}else {borrowedCount = ids.length;if (borrowedCount > borrowedIDS.length) {borrowedIDS = new BorrowedUidAndBookId[borrowedCount];}// 将借阅信息拷贝到borrowedID中for (int i = 0; i < borrowedCount; i++) {borrowedIDS[i] = ids[i];}}}private void storeBorrowedBook() {analyzingBorrowedBook.writeID(borrowedIDS,Constant.BORROWED_BOOK_FILE);}//借阅图书public void borrowBook() {}//归还图书public void returnBook() {}// 查看个⼈借阅情况public void viewBorrowBooks() {}}

三. 方法实现

(一)管理员方法

(1)addBook

添加图书

1. proxyUser中

起到跳转作用

    public void addBook() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).addBook();}
2. Root中

准备书的信息

 //上架图书public void 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(); // 输⼊出版年份scanner.nextLine(); // 吞掉换⾏符LocalDate shelfDate = LocalDate.now(); // 当前时间作为上架时间Book newBook = new Book(title, author, category, year, shelfDate); // 建新书对象//调⽤图书类 添加图书library.addBook(newBook);}
3. Library中

注意一定要写入文件当中

public void addBook(Book newBook) {if (bookCount >= books.length) {grow();}if (bookCount == 0) {newBook.setBookId(1);}else {newBook.setBookId(bookCount+1);}books[bookCount++] = newBook;writeBook();System.out.println("图书 "+newBook.getTitle()+"上架成功!");}

(2)updateBook

更新图书信息

1. proxyUser中

起到跳转作用

   //更新书籍操作public void updateBook() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).updateBook();}
2. Root中

准备书的信息

    //图书修改 ⽀持修改书名 作者 类别public void updateBook() {//1. 先展⽰⼀下⽬前的所有书籍library.displayBooks();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);}
3. Library中

注意一定要写入文件当中

    public void updateBook(Book book) {//先找到该书是哪个下标int index = searchByIdReturnIndex(book.getBookId());books[index] = book;System.out.println("图书:"  + book.getTitle() +" 更新成功!");//⼀定要进⾏存储writeBook();}

(3)removeBook

删除图书

1. proxyUser中

起到跳转作用

    public void removeBook() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).removeBook();}
2. Root中

通过id查找是否存在这本书

    public void removeBook() {//1. 先展⽰⼀下⽬前的所有书籍library.displayBooks();System.out.println("请输⼊要删除的图书id:");int bookId = scanner.nextInt();scanner.nextLine(); // 吞掉换⾏符Book book = library.searchById(bookId);if (book == null) {System.out.println("没有你要删除的书!");return;}library.removeBook(book);System.out.println("图书:" + book.getTitle() + " 已经删除!");}
3. Library中

在图书馆删除书的信息,然后写入文件当中

    public void removeBook(Book book) {loadAllBook();int index = searchByIdReturnIndex(book.getBookId());for (int i = index; i < bookCount - 1; i++) {books[i] = books[i + 1];}books[bookCount - 1] = null;bookCount--;writeBook();}

(4)borrowCount

查看所有图书借阅次数

1. proxyUser中

起到跳转作用,又因为借阅图书和普通用户有关

   public void borrowCount( ) {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).borrowCount();}
2. Root中

因为借阅图书和普通用户及图书馆有关,所以只能跳转到图书馆

   public void borrowCount() {library.borrowCount();}
3. Library中

先加载图书,然后在图书馆找书的借阅信息,最后打印出来

    public void borrowCount() {loadAllBook();if (bookCount == 0) {System.out.println("没有书籍!");return;}for (int i = 0; i < bookCount; i++) {Book book = books[i];System.out.println("书名:"+book.getTitle()+ " 借阅次数:"+book.getBorrowCount());}}

(5)generateBook

查看最受欢迎的前K本书

1. proxyUser中

起到跳转作用

    public void generateBook() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).generateBook();}
2. Root中

先让用户输入k的值,k值也应该做限定

    public void generateBook() {System.out.println("请输⼊你要查看的最受欢迎的前K本书,注意k值不能超过:"+library.getBookCount());int k = scanner.nextInt();if(k <= 0 || k > library.getBookCount()) {System.out.println("没有最受欢迎的前"+k+"本书!");return;}library.generateBook(k);}
3. Library中

书中的书籍都是按照添加顺序即id排序的,我们不希望打乱该顺序,所以额外申请一个tmp数组,来按照借阅次数排序,这需要book当中实现comparable接口

 public void generateBook(int k) {loadAllBook();Book[] tmp = new Book[getBookCount()];for (int i = 0; i < bookCount; i++) {tmp[i] = books[i];}Arrays.sort(tmp);for (int i = 0; i < k; i++) {Book book = tmp[i];System.out.println(" 书名:"+ book.getTitle()+" 作者:"+ book.getTitle()+" 借阅次数:"+book.getBorrowCount());}}
4. Book中
    @Overridepublic int compareTo(Book o) {return o.borrowCount - this.borrowCount;}

(6)checkInventoryStatus

查看库存状态

1. ProxyUser中

跳转作用

    public void checkInventoryStatus() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).checkInventoryStatus();}
2. Root中

跳转作用

3. Library中

打印每本书的借阅状态和名字

   public void checkInventoryStatus() {loadAllBook();for (int i = 0; i < bookCount; i++) {Book book = books[i];String status = book.isBorrowed() ? "已借出" : "在馆";System.out.println("书名:"+book.getTitle()+" ⽬前状态:"+status);}}

(7)checkAndRemoveOldBooks

移除上架超过1年的书籍

1. ProxyUser中

跳转作用

 public void checkAndRemoveOldBooks() {checkRealUserWhetherAdminUser("你不是root用户!!!");((Root)proxyUser).checkAndRemoveOldBooks();}
2. Root中

跳转作用

    public void checkAndRemoveOldBooks() {library.checkAndRemoveOldBooks();}
3. Library中
  1. 加载书籍信息
  2. 先获取当前时间戳
    long currentTimestamp = System.currentTimeMillis();
  3. 将当前时间转化为LocalDate类型
    LocalDate currentDate = Instant.ofEpochMilli(currentTimestamp).atZone(ZoneId.systemDefault()).toLocalDate();
  4. 遍历books数组,获取每本书的LocalDate上架时间
    LocalDate specifiedDate = book.getShelfDate();
  5. 按年份比较LocalDate上架时间
    long yearsBetween = ChronoUnit.YEARS.between(specifiedDate, currentDate);
  6. 查看相差年份大于1的情况,判断当前书是否被人借阅,被人借阅则不能删除,没有被借阅则可以被删除,但要判断是否删除
    if (yearsBetween > 1) {
    flag = true;
    if (book.isBorrowed()) {
    System.out.println(“对不起 " + book.getTitle() + " 正在被借阅,”);
    return;
    }
    System.out.print(“图书 " + book.getTitle() + " 已经上架超过⼀年,是否 移除? (Yes/NO):”);
    scanner.nextLine();
    String response = scanner.nextLine();
    if (response.equalsIgnoreCase(“yes”)) {
    removeBook(book);
    }
    }
  7. 判断是否有书籍大于1年,没有的话给出提示
    if (flag) {
    return;
    }
    System.out.println(“没有上架超过⼀年的图书!”);
 public void checkAndRemoveOldBooks() {loadAllBook();// 获取当前时间戳long currentTimestamp = System.currentTimeMillis();// 将当前时间戳转换为 LocalDateLocalDate currentDate = Instant.ofEpochMilli(currentTimestamp).atZone(ZoneId.systemDefault()).toLocalDate();boolean flag = 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) {flag = true;if (book.isBorrowed()) {System.out.println("对不起 " + book.getTitle() +  " 正在被借阅,");return;}System.out.print("图书 " + book.getTitle() + " 已经上架超过⼀年,是否 移除? (Yes/NO):");scanner.nextLine();String response = scanner.nextLine();if (response.equalsIgnoreCase("yes")) {removeBook(book);}}}if (flag) {return;}System.out.println("没有上架超过⼀年的图书!");}

(二)普通用户方法

(8)borrowBook

借阅书籍,且只能是普通用户才能借阅书籍

1. ProxyUser中

代理NormalUser,跳转作用

    public void borrowBook() {checkRealUserWhetherNormalUser("请切换普通用户");((NormalUser)proxyUser).borrowBook();}
2. NormalUser
  1. 先展示书架的书
  2. 没有书则不能借阅
  3. 根据展示来输入要借阅的书的id
  4. 加载借阅书籍的信息
  5. 根据id查找该本书,如果没有找到,提示用户,并且结束进程
  6. 如果有该本书,那么先查找该本书的借阅信息,查看该本书是否被借阅过
  7. 如果被借阅过那么要判断是被自己借阅过还是别人借阅过,打印出借阅人的id与名字
  8. 没有被借阅过,那么开始借阅,跳转到图书馆开始借阅,并且将你的id与名字,以及书的id封装到BorrowedUidAndBookId中
  9. 写入到BorrowBook中
  10. 最后提示借阅成功
    public void borrowBook() {library.displayBooks();// 没有书不能借阅if (library.getBookCount() == 0) {System.out.println("对不起暑假没有书籍,你不能借阅!!!");return;}// 输入信息System.out.println("请输入你要节约的书籍id:");int bookId = scanner.nextInt();// 查找书籍Book book = library.searchById(bookId);if (book == null) {System.out.println("不好意思没有你要借阅的该书籍!!!");return;}// 加载借阅书籍loadBorrowedBook();// 查看借阅情况,观察有没有被借阅过for (int i = 0; i < borrowedCount; i++) {// 被借阅过了,分两种情况if (borrowedIDS[i].getBookId() == book.getBookId()) {// 被自己借阅过if (ID == borrowedIDS[i].getUserId()) {System.out.println("该书 " + book.getTitle() +" 已经被你节约过!" + "借阅人:" + borrowedIDS[i].getName() + " 你的ID:" + borrowedIDS[i].getUserId());return;}else {System.out.println("该书 " + book.getTitle() +" 已经被别人节约过!" + "借阅人:" + borrowedIDS[i].getName() + " 他的ID:" + borrowedIDS[i].getUserId());return;}}}// 没有被借阅过,那么你可以借阅library.borrowBook(bookId);// 将借阅信息存储到数组中borrowedIDS[borrowedCount++] = new BorrowedUidAndBookId(ID,bookId,name);// 写入到BorrowedUidAndBookId中writeBorrowedBook();System.out.println("借阅书籍 " + book.getTitle() +" 成功!!!");}
3. Library中
  1. 加载书籍信息
  2. 根据传入的bookId来找到对应书籍
  3. 将该书籍的isBorrowed改为true
  4. 写入文件
    public void borrowBook(int bookId) {loadAllBook();Book book = searchById(bookId);book.setBorrowed(true);book.incrementBorrowed();writeBook();}

(9)returnBook

归还书籍

1. proxyUser

跳转

  public void returnBook() {checkRealUserWhetherNormalUser("请切换普通用户");((NormalUser)proxyUser).returnBook();}
2. NormalUser
  1. 先加载借阅信息
  2. 如果借阅次数为0,那么不能归还,结束进程
  3. 打印当前所有书籍的借阅信息
  4. 输入要归还的书籍id
  5. 查找该书,为null则不用归还
  6. 有这本书,就要查看借阅表中有没有该书
  7. 遍历借阅表中有这本书,说明该属被借阅了,那么比较借阅id与本人id,相同则可以归还,不相同那么不能归还,说明是别人借的,要打印出借阅人的id与名字,都结束进程
  8. 归还的时候采用最后一个覆盖该位置信息的方法,将借阅数组最后一个置为null,借阅数量-1,并写入借阅表
  9. 遍历借阅表结束,都没有结束程序,那么说明这本书,没有被借出去
    public void returnBook() {// 加载借阅书籍loadBorrowedBook();// 判断借阅次数if (borrowedCount == 0) {System.out.println("当前没有任何借阅书籍,你不能归还!!!");return;}// 打印借阅情况System.out.println("当前所有的借阅书籍情况如下:");library.disBorrowedStatus();// 输入归还书籍idSystem.out.println("请输入你要归还的书籍id");int bookId = scanner.nextInt();// 查找书籍Book book = library.searchById(bookId);// 为null结束进程if (book == null) {System.out.println("对不起,并没有该书籍!!!");return;}// 遍历借阅表for (int i = 0; i < borrowedCount; i++) {// 借阅表中有这本书if (borrowedIDS[i].getBookId() == bookId) {// 判断是不是自己借阅的这本书if (ID == borrowedIDS[i].getUserId()) {// 可以归还library.returnBook(bookId);System.out.println("归还" + book.getTitle() + "成功!" + "归还人:" + borrowedIDS[i].getName());// 将归还的书从借阅表删除borrowedIDS[i] = borrowedIDS[borrowedCount - 1];// 清空最后一个borrowedIDS[borrowedCount - 1] = null;borrowedCount--;// 写入借阅表writeBorrowedBook();return;}else {System.out.println("对不起, " + book.getTitle() + " 不是你借阅的,你不能归还!!!" + "借阅人是:" + borrowedIDS[i].getName() + " 他的ID:" + borrowedIDS[i].getUserId());return;}}}// 遍历完借阅表,都没有结束进程System.out.println("对不起,这本书没有被借阅哦~~~");}
3. Library中

加载书的信息,根据书的id找到该书,并将该书的isBorrowed置为false,并写入文件

    public void returnBook(int bookId) {loadAllBook();Book book = searchById(bookId);book.setBorrowed(false);writeBook();}

(10)viewBorrowHistory

查看个人正在借阅所有书的情况

1. proxyUser

代理,跳转

    public void viewBorrowHistory() {checkRealUserWhetherNormalUser("请切换普通用户");((NormalUser)proxyUser).viewBorrowBooks();}
2. NormalUser
  1. 加载借阅情况
  2. 如果borrowedCount为0,那么当前没有借阅任何书籍
  3. 不为0,那么遍历借阅表,打印与自己id相同的借阅书籍,
  4. 设置一个布尔变量,打印则改变值,来最后判断是否真的借阅了书籍
    public void viewBorrowBooks() {loadBorrowedBook();//读取当前借阅所有⽤⼾的借阅书籍的情况System.out.println("您的借阅情况如下:");if (borrowedCount == 0) {System.out.println("对不起,当前借阅表没有任何正在借阅的记录!!!");return;}// 遍历借阅表// 设置一个标记boolean flag = true;for (int i = 0; i < borrowedCount; i++) {// 查找与自己借阅id相同的信息if (borrowedIDS[i].getUserId() == ID) {Book book = library.searchById(borrowedIDS[i].getBookId());System.out.println(book);flag = false;}}if (flag) {System.out.println("对不起,您当前没有正在借阅的书籍!!!");}}

(三)共同方法

(11)searchBook

查找图书,我们设置根据名字来查找,又因为书名可能重复,所以我们遍历数组找

    public void searchBook() {loadAllBook();System.out.println("请输⼊你要查找的图书的名称:");String title = scanner.nextLine();boolean flag = true;for (int i = 0; i < bookCount; i++) {if (books[i].getTitle().equalsIgnoreCase(title)) {System.out.println("找到了你要查找的书,书的详细信息如下:");System.out.println(books[i]);flag = false;}}if (flag) {System.out.println("没有你要找的这本书,你查找的书名为:" + title);}}

(12)exit

退出系统的方法

  public void exit() {System.out.println("系统已退出。。。");System.exit(0);}

(13)displayBooks

打印当前所有图书,bookCount为0,则说明没有书籍,否则就打印

   public void displayBooks() {loadAllBook();System.out.println("当前图书馆当中所有的图书: ");if (bookCount == 0) {System.out.println("当前没有任何图书!!!");return;}for (int i = 0; i < bookCount; i++) {System.out.println(books[i]);}}

(14)start

切换角色的方法,切换角色无非就是重新跳转到生成挑选角色的方法,我们可以把生成角色的方法封装起来,每次调用可以回到最初状态

package start;import factory.IUserFactory;
import factory.NormalFactory;
import factory.RootFactory;
import user.NormalUser;
import user.ProxyUser;
import user.Root;
import user.User;import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-17* Time: 19:32*/
public class LibrarySystem {public static void main(String[] args) {start();}public static void start() {IUserFactory rootFactory = new RootFactory();User rootFactoryUser = rootFactory.createUser("然",1001);IUserFactory normalFactory = new NormalFactory();User normalFactoryUser1 = normalFactory.createUser("🤪",1002);User normalFactoryUser2 = normalFactory.createUser("🤡",1003);ProxyUser proxyUser1 = new ProxyUser(rootFactoryUser);ProxyUser proxyUser2 = new ProxyUser(normalFactoryUser1);ProxyUser proxyUser3 = new ProxyUser(normalFactoryUser2);ProxyUser user = getUsers(proxyUser1,proxyUser2,proxyUser3);while (true) {int choice = user.display();user.handleOperation(choice);}}public static ProxyUser getUsers (ProxyUser proxyUser1, ProxyUser proxyUser2,ProxyUser proxyUser3) {ProxyUser user = selectProxyRole(proxyUser1,proxyUser2,proxyUser3);while (user == null) {user = selectProxyRole(proxyUser1,proxyUser2,proxyUser3);}return user;}public static ProxyUser selectProxyRole(ProxyUser proxyUser1, ProxyUser proxyUser2, ProxyUser proxyUser3) {System.out.println("选择⻆⾊进⾏登录:");System.out.println("1.管理员(root)\n2.普通⽤⼾(滑稽🤪)\n3.普通⽤⼾(小丑🤡)\n4.退出系统\n");Scanner scanner = new Scanner(System.in);int choice = scanner.nextInt();switch (choice) {case 1:return proxyUser1;case 2:return proxyUser2;case 3:return proxyUser3;case 4:System.out.println("系统已退出..");System.exit(0);break;default:System.out.println("输入的无效操作,请重新选择:");return null;}return null;}
}

四. 总结

该博客花了小编多天时间,拓展了一两个小功能,希望可以博得你的一个点赞,如果有需要,可以到我的gitee上自取
码云链接:https://gitee.com/jinghua-c/project

http://www.lryc.cn/news/592501.html

相关文章:

  • 文件上传 ,显示文件列
  • [3-02-01].第01章:框架概述 - Spring生态
  • QT窗口(4)-浮动窗口
  • 如何阅读Spring源码
  • JavaSE -- 数据操作流
  • 亚马逊广告高级玩法:如何通过ASIN广告打击竞品流量?
  • 利用steps()分步实现奔跑的小熊案例
  • IDEA 中 Maven 配置:当前项目与新项目的统一设置方法
  • 基于单片机金沙河粮仓环境监测系统设计与实现
  • STM32之L298N电机驱动模块
  • Maven 配置文件核心配置:本地仓库、镜像与 JDK 版本
  • JVM常用运行时参数说明
  • sizeof和strlen的区别
  • 【AI News | 20250717】每日AI进展
  • 通信算法之294:LTE系统中的整数倍频偏估计
  • 【数据结构初阶】--双向链表(一)
  • 【Python】python 爬取某站视频批量下载
  • stack and queue 之牛刀小试
  • SymAgent(神经符号自学习Agent)
  • 实习十三——传输层协议
  • 多级反馈队列
  • JS获取 CSS 中定义var变量值
  • 路由的概述
  • 饿了么app 抓包 hook
  • three初体验
  • 【基座模型】Qwen3报告总结
  • OpenTelemetry学习笔记(四):OpenTelemetry 语义约定,即字段映射(1)
  • 二、Dify 版本升级教程(LInux-openeuler)
  • 软件维护全维度解析:从修复到进化的生命周期管理
  • linux制作镜像、压缩镜像、烧录的方法