【JavaSE】(7)图书管理系统

一、需求设计

1、登录功能

---------- 欢迎来到图书管理系统 ----------

请输入您的姓名:

(输入一个字符串)

请选择访问角色:1. 普通用户 2. 管理员

(输入 1 or 2)

(根据选择,进入角色对应系统,打印功能菜单)

--------------------- 1. xxx ---------------------

--------------------- 2. xxx ---------------------

……

2、角色操作功能

普通用户:

  • 查询图书
  • 借阅图书
  • 归还图书
  • 退出系统

管理员:

  • 查询图书
  • 增加图书
  • 删除图书
  • 显示图书
  • 退出系统

(进入角色后,可反复执行不同操作,直到退出系统)

二、需求分析

我们要使用的对象分为这3类,角色操作书籍。

1、User

  • 分为 NormalUser 和 AdminUser。
  • 包含 userName、OperationList 成员变量。应设置为 public ,因为子类需要访问它们
  • menu 成员方法(打印操作菜单,接收选项输入,并返回选项编号)。
  • doOperations 成员方法(根据选项编号,执行 OperationList 中的操作)。
  • userName 的 getter 方法和 setter 方法(在未来可以扩展 “修改用户名” 功能)。
  • 由于不同的角色所拥有的操作不同,menu 方法在 User 中无法实现,因此 User 可设定为抽象类,menu 设定为抽象方法,由不同的角色继承 User 类后,重写 menu 方法。

2、Operation

  • 分为 7 种操作。
  • 包含 work 成员方法,用于实现操作。
  • 由于不同操作的实现不同,work 方法无法在 Operation 中实现,因此可将 Operation 设定为接口,由不同的操作类实现该接口,重写 work 方法。

3、Book

  • 包含 bookName、authorName、price、isBorrowed 、bookType 成员变量。
  • 构造方法,初始化成员变量。
  • 包含所有成员变量的 getter、setter 方法(在未来可以扩展 “管理员修改书籍信息” 功能)。
  • 重写 toString 方法,打印 book 对象。

4、BookShelf

  • 为了方便管理所有的 Book 对象,设置 BookShelf 类,因此包含 bookList 成员变量。(为什么不设置 OperationList 类?operationList 在确定角色的时候,就已经确定所有操作,且不可更改,不需要对其进行增删改,只需对列表进行访问即可;而 bookList 中的元素在变化、长度也在变化,为了避免冗余代码,需要将 bookList 包装为 BookShelf 类)
  • DEFAULT_SIZE 成员常量,即书架容量默认值。
  • usedSize 成员变量,已使用的书架容量。
  • 构造方法,初始化成员变量。
  • 包含所有成员变量的 getter 和 setter 方法(查询、增加、删除、显示、借阅、归还操作需要用到)。

5、Main 类

  • 包含 login 方法,实现用户名输入、角色选择操作,并返回用户对象。
  • 包含 main 方法,作为程序入口,实现登录功能,然后循环执行对应角色操作。

        综上所述,项目分为 user 包、operation 包、book 包,默认包(根包)包含以上三种包,并包含 Main 类用于控制主逻辑,目录如下:

三、代码实现

代码链接:test_2025_1_20 · 小猪咪/JavaSE Practice - 码云 - 开源中国

1、user 包

(1)User 抽象类

package user;

import book.BookShelf;
import operation.IOperational;

public abstract class User {
    public String userName;
    public IOperational[] operationList;

    public User(String userName) {
        this.userName = userName;
    }

    public abstract int menu();
    public void doOperation(int choice, BookShelf bookShelf){
        this.operationList[choice].work(bookShelf);
    }
}

(2)NormalUser 类

package user;

import operation.*;

import java.util.Scanner;

public class NormalUser extends User{

    public NormalUser(String userName) {
        super(userName);
        this.operationList = new IOperational[] {
                new ExitSystem(),
                new FindBook(),
                new BorrowBook(),
                new ReturnBook()
        };
    }

    @Override
    public int menu() {
        System.out.println("--------------- 普通用户 ---------------");
        System.out.println("-------------- 1.查询图书 --------------");
        System.out.println("-------------- 2.借阅图书 --------------");
        System.out.println("-------------- 3.归还图书 --------------");
        System.out.println("-------------- 0.退出系统 --------------");
        Scanner scanner = new Scanner(System.in);
        int choice;
        while (true) {
            System.out.println("请选择您的操作:");
            choice = scanner.nextInt();
            scanner.nextLine(); // 吃掉回车
            if (choice >= 0 && choice <= 3)
                break;
            else
                System.out.println("没有该选项,请重新选择!");
        }
        return choice;
    }
}

(3)AdminUser 类

package user;

import operation.*;

import java.util.Scanner;

public class AdminUser extends User{

    public AdminUser(String userName) {
        super(userName);
        this.operationList = new IOperational[] {
                new ExitSystem(),
                new FindBook(),
                new AddBook(),
                new DeleteBook(),
                new ShowBooks()
        };
    }

    @Override
    public int menu() {
        System.out.println("---------------  管理员  ---------------");
        System.out.println("-------------- 1.查询图书 --------------");
        System.out.println("-------------- 2.增加图书 --------------");
        System.out.println("-------------- 3.删除图书 --------------");
        System.out.println("-------------- 4.显示图书 --------------");
        System.out.println("-------------- 0.退出系统 --------------");
        Scanner scanner = new Scanner(System.in);
        int choice;
        while (true) {
            System.out.println("请选择您的操作:");
            choice = scanner.nextInt();
            scanner.nextLine(); // 吃掉回车
            if (choice >= 0 && choice <= 4)
                break;
            else
                System.out.println("没有该选项,请重新选择!");
        }
        return choice;
    }
}

2、operation 包

(1)IOperational 接口

package operation;

import book.BookShelf;

public interface IOperational {
    void work(BookShelf bookShelf);
}

(2)FindBook 类

package operation;

import book.Book;
import book.BookShelf;

import java.util.Scanner;

public class FindBook implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        System.out.println("请输入您要查询的书籍名称:");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();

        // 遍历书架
        int usedSize = bookShelf.getUsedSize();
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            // 找到图书,打印书籍信息
            if(book.getBookName().equals(bookName)) {
                System.out.println("查询成功,书籍信息如下:");
                System.out.println(book);
                return;
            }
        }
        // 未找到书籍
        System.out.println("查询失败,本系统没有此书。");
    }
}

(3)BorrowBook 类

package operation;

import book.Book;
import book.BookShelf;

import java.util.Scanner;

public class BorrowBook implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        System.out.println("请输入您要借阅的书籍名称:");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();

        // 遍历书架
        int usedSize = bookShelf.getUsedSize();
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            // 找到图书,查询是否被借阅
            if(book.getBookName().equals(bookName)) {
                // 未被借阅,则借出
                if(!book.isBorrowed()){
                    book.setBorrowed(true);
                    System.out.println("借阅成功!");
                    System.out.println(book);
                }
                else System.out.println("该书已被借出!");
                return;
            }
        }
        // 未找到
        System.out.println("本系统没有此书!");
    }
}

(4)ReturnBook 类

package operation;

import book.Book;
import book.BookShelf;

import java.util.Scanner;

public class ReturnBook implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        System.out.println("请输入您要归还的书籍名称:");
        Scanner scanner = new Scanner(System.in);
        String bookName = scanner.nextLine();

        // 遍历书架
        int usedSize = bookShelf.getUsedSize();
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            // 找到图书,查询是否被借阅
            if(book.getBookName().equals(bookName)) {
                // 未被借阅,则不需要归还
                if(!book.isBorrowed())
                    System.out.println("该书未被借出,请不要重复归还!");
                // 归还书籍
                else {
                    book.setBorrowed(false);
                    System.out.println("归还成功!");
                    System.out.println(book);
                }
                return;
            }
        }
        // 未找到
        System.out.println("本系统没有收录此书,不需要归还!");
    }
}

(5)AddBook 类

package operation;

import book.Book;
import book.BookShelf;

import java.util.Arrays;
import java.util.Scanner;

public class AddBook implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {

        // 书架已经放满,扩容
        if(isFull(bookShelf)) {
            Book[] bookList = bookShelf.getBookList();
            double newLength = bookList.length * 1.5;
            // 大于 bookList 长度的部分,Arrays.copyOf 会设置为数组元素的默认值
            bookShelf.setBookList(Arrays.copyOf(bookList, (int)newLength));
        }

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入书名:");
        String bookName = scanner.nextLine();
        System.out.println("请输入作者:");
        String authorName = scanner.nextLine();
        System.out.println("请输入书籍类型:");
        String bookType = scanner.nextLine();
        System.out.println("请输入书籍价格:");
        float price = scanner.nextFloat();

        int usedSize = bookShelf.getUsedSize();
        // 遍历书架
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            // 书籍已存在
            if(book.getBookName().equals(bookName)) {
                System.out.println("该书已被收录,请勿重复添加!");
                return;
            }
        }

        // 添加书籍
        bookShelf.setBook(usedSize, new Book(bookName, authorName, bookType, price));
        bookShelf.setUsedSize(usedSize + 1);
    }

    public boolean isFull(BookShelf bookShelf){
        return bookShelf.getBookList().length == bookShelf.getUsedSize(); // 书架容量 == 已用容量
    }
}

(6)DeleteBook 类

package operation;

import book.Book;
import book.BookShelf;

import java.util.Scanner;

public class DeleteBook implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您要删除的书籍名称:");
        String bookName = scanner.nextLine();

        int usedSize = bookShelf.getUsedSize();
        // 遍历书架
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            // 书籍存在,删除
            if (book.getBookName().equals(bookName)) {
                for(int j = i; j < usedSize - 1; j++)
                    bookShelf.setBook(j, bookShelf.getBook(j + 1));
                bookShelf.setUsedSize(usedSize - 1);
                bookShelf.setBook(usedSize - 1, null);
                return;
            }
        }
        // 书籍不存在
        System.out.println("没有此书,无需删除!");
    }
}

(7)ShowBook 类

package operation;

import book.Book;
import book.BookShelf;

public class ShowBooks implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        // 遍历书架
        int usedSize = bookShelf.getUsedSize();
        for (int i = 0; i < usedSize; i++) {
            Book book = bookShelf.getBook(i);
            System.out.println(book);
        }
    }
}

(8)ExitSystem 类

package operation;

import book.BookShelf;

public class ExitSystem implements IOperational{
    @Override
    public void work(BookShelf bookShelf) {
        // 释放书架空间
        int usedSize = bookShelf.getUsedSize();
        for (int i = 0; i < usedSize; i++)
            bookShelf.setBook(i,null);
        bookShelf.setUsedSize(0);
        // 退出系统
        System.exit(0);
    }
}

3、book 包

(1)Book 类

package book;

public class Book {
    private String bookName;
    private String authorName;
    private String bookType;
    private float price;
    private boolean isBorrowed; // 默认设置为 false 没有被借出

    public Book(String bookName, String authorName, String bookType, float price) {
        this.bookName = bookName;
        this.authorName = authorName;
        this.bookType = bookType;
        this.price = price;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public String getBookType() {
        return bookType;
    }

    public void setBookType(String bookType) {
        this.bookType = bookType;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public boolean isBorrowed() {
        return isBorrowed;
    }

    public void setBorrowed(boolean borrowed) {
        isBorrowed = borrowed;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookName:'" + bookName + '\'' +
                ", authorName:'" + authorName + '\'' +
                ", bookType:'" + bookType + '\'' +
                ", price:" + price +
                ", isBorrowed:'" + (isBorrowed ? "已被借出" : "未被借出") + '\'' +
                '}';
    }
}

(2)BookList 类

package book;

public class BookShelf {
    private Book[] bookList;
    private static final int DEFAULT_SIZE = 4;
    private int usedSize;

    public BookShelf() {
        this.bookList = new Book[DEFAULT_SIZE];
        this.bookList[0] = new Book("三体", "刘慈欣", "科幻", (float)83.8);
        this.bookList[1] = new Book("射雕英雄传", "金庸", "武侠", (float)94.25);
        this.bookList[2] = new Book("倾城之恋", "张爱玲", "情感", (float)24.69);
        this.usedSize = 3;
    }

    public Book[] getBookList() {
        return bookList;
    }

    public void setBookList(Book[] bookList) {
        this.bookList = bookList;
    }

    public Book getBook(int pos) {
        return this.bookList[pos];
    }

    public void setBook(int pos, Book book) {
        this.bookList[pos] = book;
    }

    public int getUsedSize() {
        return usedSize;
    }

    public void setUsedSize(int usedSize) {
        this.usedSize = usedSize;
    }
}

4、Main 类

import book.BookShelf;
import user.*;

import java.util.Scanner;

public class Main {
    public static User login(){
        System.out.println("---------- 欢迎来到图书管理系统 ----------");
        System.out.println("请输入用户名:");
        Scanner scanner = new Scanner(System.in);
        String userName = scanner.nextLine();

        while(true){
            System.out.println("请选择角色 (1.普通用户 or 2.管理员):");
            int choice = scanner.nextInt();
            if(choice == 1)
                return new NormalUser(userName);
            else if(choice == 2)
                return new AdminUser(userName);
            else System.out.println("没有此选项,请重新输入!");
        }
    }
    public static void main(String[] args) {
        User user = login(); // 登录
        BookShelf bookShelf = new BookShelf();
        while (true) {
            int choice = user.menu();
            user.doOperation(choice, bookShelf);
        }
    }
}

四、功能测试

1、登录功能测试

(1)普通用户登录

(2)管理员登录

2、操作功能测试

(1)查询图书

查询不存在的书籍:

查询存在的书籍:

(2)借阅图书

借阅不存在的书籍:

借阅存在且被未借出的书籍:

借阅存在且被借出的书籍:

(3)归还图书

归还不存在的书籍:

归还存在且被借出的书籍:

归还存在且被未借出的书籍:

(4)添加图书及显示图书

书架容量,默认为 4,以初始化放入三本书。

添加已存在的书籍:

书架未满,添加图书:

书架已满,添加图书:

显示图书:

(5)删除图书

删除图书不存在:

删除图书存在:

(6)退出系统

五、总结

        本图书管理系统用到了 Java 的基本语法、继承、抽象类、接口、动态规划等知识,是个不错的小练习。

六、补充 -- Statistic 插件

File >> settings >> Plugins >> 搜索 Statistic >> install >> Apply,刷新,可以看到项目有 363 行代码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值