如何用Java实现一个简易的图书管理系统

目录

确立对象

确立这些对象的基本信息和功能

书架

管理员和普通用户

各对象之间进行交互


既然是Java实现,那么就应该从面向对象的思想入手。首先需要确立有哪些对象,这些对象的功能又是什么,然后通过这些对象的交互实现这样一个建议的图书管理系统。

要实现图书管理系统,步骤可简单分为三步:

  1. 确立对象
  2. 确立这些对象的基本信息和功能
  3. 各对象之间进行交互

确立对象

首先想一想现实中的图书管的对象,有书、书架、管理员、借书的人等等。那么对象就确定了:书、书架、管理员、普通用户。

确立这些对象的基本信息和功能

书并不是一个生命体,因此它不可能具有什么功能,它只可能有一些特定的信息。因此创建书类只需要创建相应的基本信息即可:书名、作者、书的类别、价格、出版社,是否被借出等。

当然,也可以把这些基本信息封装起来,减少权限的滥用:

public class Book {
    private String bookName;//书名
    private String author;//作者
    private String type;//类型
    private double price;//价格
    private boolean isBorrowed;

    public String getBookName() {
        return bookName;
    }

    public Boolean getBorrowed() {
        return isBorrowed;
    }

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

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

    public void setAuthor(String author) {
        this.author = author;
    }

    public void setType(String type) {
        this.type = type;
    }

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

    public void setPress(String press) {
        this.press = press;
    }

    private String press;//出版社

    @Override
    public String toString() {
        return "Book{" +
                "书名:'" + bookName + '\'' +
                ", 作者:'" + author + '\'' +
                ", 类别:'" + type + '\'' +
                ", 价格:" + price +
                ", 出版社:'" + press + '\'' +
                ", 是否被借出:" + isBorrowed +
                '}';
    }
}

书架

书架显然和书一样不需要功能,而它的信息包括有多少个书架,每个书架上可以放多少本书,也需要直到书架上目前放有多少本。当然,现实中的图书馆书籍并不是随便乱放的,一般来说某一类的书都会放在一起,因此可以类似的规定某个书架上放某个特定类型的书。同样的,可以将某些信息隐藏起来,也就是封装,减少权限的滥用:

public class BookShelf {
    public static final int BOOKSHELF_COUNT = 6;//一共有6个书架
    public static final int BOOKS_MAX = 100;//每个书架上最多有100本书
    public String[] bookStyles = new String[] { "古典文学", "外国文学", "儿童文学", "专业知识普及读物", "实用类大众书", "其他类别" };//书的不同种类
    public Book[][] bookList = new Book[BOOKSHELF_COUNT][BOOKS_MAX];//定义整个系统所能容纳书的数量
    private int bookSize[] = { 0, 0, 0, 0, 0, 0 };//每个书架上放有几本书

    public void typeMenu() {
        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、其他类别");
    }
    public int getBookSize(int index) {
        return bookSize[index];
    }

    public void setBookSize(int bookSize, int index) {
        this.bookSize[index] = bookSize;
    }
}

管理员和普通用户

首先管理员和普通用户有一定的共性,因此可以先定义一个共同的父类,从而提高代码的复用率。管理员和用户都需要登录才能进行后续的操作,因此都需要有用户名和密码,同时需要一个登录功能。但此时管理员和普通用户是有所区别的,管理员只有一个,而普通用户可以有多个甚至无数个,只要愿意注册,多少个普通用户都可以。因此创建的信息略有不同,管理员信息可以直接赋值确定,而用户信息可以存放到数组当中,如果注册账号,就在数组相应的位置上存储相应的用户名和密码,当用户输入用户名和密码时,在数组中寻找并匹配。

protected static final int GENERAL_NUM = 50;
//管理员用户名和密码组
private String administrator = "zhangsan";
private String administratorPassword = "123456";
//普通用户用户名和密码组
public String[] generalUser= new String[GENERAL_NUM];
public String[] generalUserPassword = new String[GENERAL_NUM];

当然,这里我们用户的数量并不是无限的,而是一个确定的值50,大家可以自己进行优化。

登录功能可以只写一个抽象函数,毕竟普通用户的登录和管理员略有不同:

管理员:将输入的字符串利用equals与已知进行比较即可

//管理员登录
@Override
String userLogin(Books.User.User user) {//返回用户名
    Scanner scanner = new Scanner(System.in);
    int time = 5;//一共5次输入机会
    System.out.println("请先登录…");
    while (time > 0) {
        System.out.println("请输入用户名:》");
        String username = scanner.nextLine();
        System.out.println("请确认密码:》");
        String password = scanner.nextLine();
        if (username.equals(user.getAdministrator()) && password.equals(user.getAdministratorPassword())) {
            System.out.println("登陆成功!");
            return username;
        }else {
            time--;
            System.out.println("用户名或密码错误,还有" + time + "次机会!!!");
        }
    }
    if (time == 0) {
        //这里抛出异常需要在外面有catch捕获
        throw new Books.User.AdministratorLoginException("多次输入错误,账户暂时被锁定!");
    }
    return null;
}

普通用户:由于有不止一个普通用户,因此将信息存放在数组中,注意用户名存放位置与密码存放位置相匹配。同时用户不仅有登录功能,还有注册功能:

public static int generalUserNum = 0;//普通用户数量
//注册用户信息
public void setGeneralUser(String[][] generalUserLogin) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入用户名:》");
    generalUserLogin[0][generalUserNum] = scanner.nextLine();
    while (generalUserNum < GENERAL_NUM) {
        System.out.println("请输入密码:》");
        generalUserLogin[1][generalUserNum] = scanner.nextLine();
        System.out.println("请确认密码:》");
        String tmp = scanner.nextLine();
        if (generalUserLogin[1][generalUserNum].equals(tmp)) {
            System.out.println("注册成功!请登录…");
            break;
        }else {
            System.out.println("两次设置的密码不一致,请重新设置密码!");
        }
    }
    generalUserNum++;
}

//用户登录
@Override
String userLogin(Books.User.User user) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入用户名:》");
    String username = scanner.nextLine();
    //查询用户是否存在
    int index = findMember(generalUser, username);
    if (index == -1) {
        System.out.println("用户名不存在!");
        while (true) {
            System.out.println("请进行操作:》1-重新登录   0-返回主菜单");
            int select = scanner.nextInt();
            if (select == 1) {
                return userLogin(user);
            }else if (select == 0) {
                return null;
            }else {
                System.out.println("选择错误,请重新选择!");
            }
        }
    }else {
        int time = 3;
        while (time > 0) {
            System.out.println("请输入密码:》");
            String password = scanner.nextLine();
            if (!password.equals(generalUserPassword[index])) {
                System.out.println("密码错误,还有" +time + "次机会!");
                time--;
            }else {
                System.out.println("登陆成功!");
                return username;
            }
        }
        throw new Books.User.GeneralUserLoginException("多次输入错误,账户暂时被锁定!");

    }
}

各对象之间进行交互

这里的交互主要有三种,一种是管理员与用户(单方面)交互,一种是管理员与书和书架交互,一种是普通用户与书和书架的交互:

首先是管理员与用户之间的交互,主要体现在管理员查询用户信息,这个没什么好说的,遍历数组一个个比较即可。

其次是管理员与书和书架之间的交互:

也就是管理员对书可以操作的功能,可以有增、删、查、改,借阅与归还,更新图书等等,这部分可以通过接口来规范实现:

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

首先是增添图书功能: 

public class AddBook implements Books.Operate.Books.IOOperateBook {

    @Override
    public void work(BookShelf bookShelf) {
        Scanner scanner = new Scanner(System.in);
        bookShelf.typeMenu();
        System.out.println("请选择所增书目的类别:》");
        int select = scanner.nextInt();
        scanner.nextLine();//清除剩余的"\n"
        while (select > 0 && select <= 6) {
            int bookNum = bookShelf.getBookSize(select - 1);
            if (bookNum < BookShelf.BOOKS_MAX) {//书架上有空位
                Book book = new Book();
                System.out.println("请输入书名:》");
                String bookName = scanner.nextLine();
                book.setBookName(bookName);
                System.out.println("请输入作者:》");
                book.setAuthor(scanner.nextLine());
                System.out.println("请输入价格:》");
                book.setPrice(scanner.nextDouble());
                scanner.nextLine();//清除剩余的"\n"
                System.out.println("请输入书籍出版社:》");
                book.setPress(scanner.nextLine());
                //书的类别
                book.setType(bookShelf.bookStyles[select - 1]);
                //把书放在书架空位上
                for (int i = 0; i <= BookShelf.BOOKS_MAX; i++) {
                    if (bookShelf.bookList[select - 1][i] == null) {
                        bookShelf.bookList[select - 1][i] = book;
                        System.out.println("添加成功!");
                        break;
                    }
                }
                bookShelf.setBookSize(bookNum + 1, select - 1);//书架位置-1
                return;
            }else {
                System.out.println("很抱歉,书架放不下了…");
                return;
            }
        }
        System.out.println("选择有误,请重新选择!");
        work(bookShelf);
    }
}

其余功能的实现方式也大同小异,并不复杂。当然,要注意书放的位置,增删操作都会使书架上的位置数量变化。

更新图书操作中,如果不更新书的类别,可以不挪动书的位置,也就是单纯的更改信息即可,但如果要更新图书类别,那就一定要把该书从书架上拿出来放到另一个书架上去,这样两个书架都要发生变化:

public class UpdateBook implements IOOperateBook{
    private void UpdateMenu() {
        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("0、保存更新");

    }
    private void updateType(BookShelf bookShelf, Book book, int[] ret) {
        Scanner scanner = new Scanner(System.in);
        //原书架上空位多一个
        int bookNum = bookShelf.getBookSize(ret[0]);
        bookShelf.setBookSize(bookNum - 1, ret[0]);

        System.out.println("请输入更新后图书的类型:》");
        String newType = scanner.nextLine();
        book.setType(newType);
        int i;
        for (i = 0; i < BookShelf.BOOKSHELF_COUNT; i++) {
            if (newType.equals(bookShelf.bookStyles[i])) {
                if (bookShelf.getBookSize(i) < BookShelf.BOOKS_MAX) {
                    //符合类型的书架上空位-1
                    bookShelf.setBookSize(bookShelf.getBookSize(i) + 1, i);
                    //书放在空位上
                    for (int j = 0; j < BookShelf.BOOKS_MAX; j++) {
                        if (bookShelf.bookList[i][j] != null) {
                            bookShelf.bookList[i][j] = book;
                            break;
                        }
                    }
                    break;
                }else {
                    System.out.println("书架上都放满了!");
                }
            }
        }
        //其他的小种类型均归为其他类型
        if (i == 6 && bookShelf.getBookSize(5) < BookShelf.BOOKS_MAX) {
            book.setType(bookShelf.bookStyles[5]);
            System.out.println("该类型比较小众,已自动归为其他类别~");
            //书架上书的数量+1,书架空位-1
            bookShelf.setBookSize(bookShelf.getBookSize(5) + 1, 5);
            //书放在空位上
            for (int j = 0; j < BookShelf.BOOKS_MAX; j++) {
                if (bookShelf.bookList[5][j] == null) {
                    bookShelf.bookList[5][j] = book;
                    break;
                }
            }
        }else {
            System.out.println("书架上都放满了!");
        }
    }
    @Override
    public void work(BookShelf bookShelf) {
        Scanner scanner = new Scanner(System.in);
        //更新图书信息
        FindBook findBook = new FindBook();
        System.out.println("请输入需要更新的书的名字:》");
        String bookName = scanner.nextLine();
        int[] ret = findBook.findBook(bookShelf, bookName);
        if (ret != null) {
            Book book = bookShelf.bookList[ret[0]][ret[1]];
            while (true) {
                UpdateMenu();
                System.out.println("请选择要进行更新的信息:》");
                int select = scanner.nextInt();
                scanner.nextLine();//清除"\n"
                switch (select) {
                    case 1:
                        System.out.println("请输入需要更新的书的名字:》");
                        book.setBookName(scanner.nextLine());
                        break;
                    case 2:
                        System.out.println("请输入更新后的作者:》");
                        book.setAuthor(scanner.nextLine());
                        break;
                    case 3:
                        updateType(bookShelf, book, ret);
                    break;
                    case 4:
                        System.out.println("请输入更新后的价格:》");
                        book.setPrice(scanner.nextDouble());
                        scanner.nextLine();//清除剩余的"\n"
                        break;
                    case 5:
                        System.out.println("请输入更新后书籍出版社:》");
                        book.setPress(scanner.nextLine());
                        break;
                    case 0:
                        System.out.println("保存成功!");
                        return;
                    default:
                        System.out.println("选择错误,请重新选择!");
                        break;
                }
            }
        }else {
            System.out.println("没有找到这本书!");
        }
    }
}

当然,交互不可能只有这些,比如说更改用户名和密码等操作,也可以添加进来。不过这都属于锦上添花的作用了。所有的一切都设计好以后,就需要把它们串联起来,形成一个真正的系统。为了方便,菜单是必不可少的,同时也可以适当的加上异常处理功能:

public class Main {
    static void menu() {
        System.out.println("************************************************");
        System.out.println("欢迎来到图书管理系统!");
        System.out.println("请选择你的身份:》1-管理员  2-普通用户");
    }
    static int backMenu() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("************************************************");
        System.out.println("1-返回菜单 0-退出程序");
        int ret = scanner.nextInt();
        while (scanner.hasNextLine()) {
            if (ret == 1 || ret == 0) {
                return ret;
            }else {
                System.out.println("选择错误!");
            }
        }
        return 0;
    }
    static int newBackMenu() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("************************************************");
        System.out.println("1-重新登陆 0-退出程序");
        int ret = scanner.nextInt();
        while (scanner.hasNextLine()) {
            if (ret == 1 || ret == 0) {
                return ret;
            }else {
                System.out.println("选择错误!");
            }
        }
        return 0;
    }
    static int BookManagementSystem(User administrator, GeneralUser generalUser, BookShelf bookShelf) {
        menu();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            int identity = scanner.nextInt();
            if (identity == 1) {
                //执行管理员的功能
                //管理员登录
                String userName = administrator.userLogin(administrator);
                while (scanner.hasNextLine()) {
                    //打印管理员的菜单
                    administrator.menu();
                    //选择操作
                    System.out.println("请选择你要进行的操作:》");
                    int choose = scanner.nextInt();
                    //管理员可操作的各种功能
                    switch (choose) {
                        case 1:
                            ChangePassword changePassword = new ChangePassword();
                            changePassword.work(administrator,userName);
                            int ret1= newBackMenu();
                            if (ret1 == 1) {
                                return BookManagementSystem(administrator, generalUser, bookShelf);
                            }else {
                                return 0;
                            }
                        case 2:
                            QueryUser queryUser = new QueryUser();
                            queryUser.work(generalUser,userName);
                            int ret2= backMenu();
                            if (ret2 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 3:
                            AddBook addBook = new AddBook();
                            addBook.work(bookShelf);
                            int ret3= backMenu();
                            if (ret3 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 4:
                            UpdateBook updateBook = new UpdateBook();
                            updateBook.work(bookShelf);
                            int ret4= backMenu();
                            if (ret4 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 5:
                            DeleteBook deleteBook = new DeleteBook();
                            deleteBook.work(bookShelf);
                            int ret5= backMenu();
                            if (ret5 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 6:
                            SearchBook searchBook = new SearchBook();
                            searchBook.work(bookShelf);
                            int ret6= backMenu();
                            if (ret6 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 7:
                            BorrowBook borrowBook = new BorrowBook();
                            borrowBook.work(bookShelf);
                            int ret7= backMenu();
                            if (ret7 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 8:
                            ReturnBook returnBook  = new ReturnBook();
                            returnBook.work(bookShelf);
                            int ret8= backMenu();
                            if (ret8 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 9:
                            ShowBooks showBooks = new ShowBooks();
                            showBooks.work(bookShelf);
                            int ret9= backMenu();
                            if (ret9 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 0:
                            System.out.println("退出程序");
                            return 0;
                        default:
                            System.out.println("选择错误,请重新选择!");
                            break;
                    }
                }
            } else if (identity == 2) {
                //普通用户菜单栏功能
                String generalUserName = null;//普通用户用户名
                while (scanner.hasNextLine()) {
                    generalUser.menu();
                    System.out.print("请选择你要进行的操作:》");
                    int choose = scanner.nextInt();
                    if (choose == 1) {
                        generalUser.setGeneralUser(generalUser.generalUserLogin);
                    } else if (choose == 2) {
                        generalUserName = generalUser.userLogin(generalUser);
                        if (generalUserName != null) {//登陆成功
                            break;
                        } else {//返回主菜单
                            return BookManagementSystem(administrator, generalUser, bookShelf);
                        }
                    } else if (choose == 0) {
                        System.out.println("退出程序中…");
                        return 0;//程序中止
                    } else {
                        System.out.println("输入错误,请重新输入!");
                    }
                }
                //打印普通用户子菜单说明登陆成功
                //执行普通用户操作
                while (scanner.hasNextLine()) {
                    generalUser.subMenu();
                    int choose1 = scanner.nextInt();
                    switch (choose1) {
                        case 1:
                            ChangePassword changePassword = new ChangePassword();
                            changePassword.work(generalUser,generalUserName);
                            return 0;
                        case 2:
                            SearchBook search = new SearchBook();
                            search.work(bookShelf);
                            int ret2= backMenu();
                            if (ret2 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 3:
                            BorrowBook borrow = new BorrowBook();
                            borrow.work(bookShelf);
                            int ret3= backMenu();
                            if (ret3 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 4:
                            ReturnBook returnBook = new ReturnBook();
                            returnBook.work(bookShelf);
                            int ret4= backMenu();
                            if (ret4 == 1) {
                                break;
                            }else {
                                return 0;
                            }
                        case 0:
                            System.out.println("退出程序!");
                            return 0;
                        default:
                            System.out.println("输入有误,请重新输入!");
                            break;
                    }
                }
                //用户登陆成功后的子菜单功能
                generalUser.subMenu();
                break;
            } else {
                System.out.println("请进行正确的操作!");
            }
        }
        return 0;
    }

    public static void main(String[] args) {
        User administrator = new Administrator();
        GeneralUser generalUser = new GeneralUser();
        InitialSomeGeneralUsers initialSomeGeneralUsers = new InitialSomeGeneralUsers();
        initialSomeGeneralUsers.initialSomeGeneralUsers(generalUser);
        BookShelf bookShelf = new BookShelf();
        InitialBooks initialBooks = new InitialBooks();
        initialBooks.work(bookShelf);
        try {
            BookManagementSystem(administrator, generalUser, bookShelf);
        } catch (InputMismatchException e) {
            System.out.println("输入格式有误!");
            e.printStackTrace();
        } catch (AdministratorLoginException | GeneralUserLoginException e) {
            e.printStackTrace();
        } finally {
            System.out.println("关闭某些无用资源…");
        }
    }
}

当然,由于这些异常并不属于Java中本身就有的,因此需要新建一个异常类,(一定要继承于RuntimeException)确保异常可以顺利捕捉到。

如果有兴趣了解其他部分功能如何实现,也可以访问我的Gitee仓库查看源码:

  • 4
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值