一、整体思路分析
对于图书管理系统,首先会有两类用户:普通用户和管理员。
其次明确他们各自应该具备的权限:
- 管理员:添加图书、删除图书、显示图书(显示所有的图书信息)、查看图书、退出系统。
- 普通用户:显示图书、查找图书、借阅图书、归还图书、退出系统。
那么大体就可以分为四个模块:图书模块(图书类和书架存放图书)、操作模块(封装用户的各类操作)、用户模块(管理员和普通用户)和主函数测试模块。
二、分模块完成功能设计
1、图书模块
a.图书类
定义图书的相关属性,带参的构造方法,各个属性的get和set方法,以及重写toString和equals方法。
public class Book { private String name;//图书名称 private String author;//图书作者 private int price;//图书价格 private String theme;//图书主题 private boolean isBorrowed;//图书是否被借出 public Book(String name, String author,int price, String theme) { this.name = name; this.price=price; this.author = author; this.theme = theme; this.isBorrowed = false;//默认未借出 } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getTheme() { return theme; } public void setTheme(String theme) { this.theme = theme; } public boolean isBorrowed() { return isBorrowed; } public void setBorrowed(boolean borrowed) { isBorrowed = borrowed; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return name + "\t"+ author + "\t" +price+"\t"+ theme + "\t" + (isBorrowed()?"已借出":"未借出" ); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Book book = (Book) o; return isBorrowed == book.isBorrowed && Objects.equals(name, book.name) && Objects.equals(author, book.author) && Objects.equals(theme, book.theme); } }
b.书架类
书架类需要定义一个图书类的数组,还有书架的容量,以及书架当前存放图书的数目,还需要定义获取指定位置图书的方法,以及指定位置修改图书的方法。对于构造方法应该是包含书架的容量,但是对于本系统的普通用户需要对图书进行相关操作,但是他没有添加用户的权限,故书架默认存放了几本图书。
public class Bookshelf { private Book[] books ;//书架类 private int size;//书架当前存放图书的数目 private int currentSize=0; public Bookshelf(int size) { books = new Book[size]; this.size=size; } public Bookshelf() { books = new Book[]{ new Book("微机原理","胡浩",55,"教材"), new Book("彼此尊重","张琪",90,"小说"), new Book("一夜暴富","小G",99,"玄幻"), null,null,null,null,null,null }; this.size=10; this.currentSize=3; } public int getCurrentSize() { return currentSize; } public void setCurrentSize(int currentSize) { this.currentSize = currentSize; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } /** * 获取指定位置的图书 * @param pos * @return */ public Book getBook(int pos){ if(pos>=size){ System.out.println("已超出书架当前容量"); }else{ return books[pos]; } return null; } public void addBook(Book book){ books[currentSize]=book; } /** * 修改指定位置的图书 * @param pos * @param book * @return */ public void modify(int pos,Book book){ if(pos>=size){ System.out.println("已超出书架当前容量"); return ; }else{ books[pos]=book; } } }
2、操作模块
由于管理员和普通用户都是对书架进行操作,可以定义一个操作接口,包含一个抽象方法,让所有的操作类都实现操作接口的方法。
public interface Operate { void work(Bookshelf books); }
a.添加图书
首先应该判断书架是否已满,若未满,则输入图书信息,然后再需要对将要添加的图书与书架中的图书进行比较,判断是否已经存在,若未存在,则添加成功,书架目前存放图书数目加一,否则无法添加。
public class AddBook implements Operate{ @Override public void work(Bookshelf books) { if(books.getCurrentSize()>= books.getSize()){ System.out.println("书架已满,无法继续添加"); }else{ System.out.println("请输入图书信息:"); System.out.println("图书名称:"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); System.out.println("图书作者:"); String author = sc.nextLine(); System.out.println("图书价格:"); int price = sc.nextInt(); System.out.println("图书主题:"); sc.nextLine(); String theme= sc.nextLine(); Book book = new Book(name, author, price, theme); for (int i = 0; i < books.getCurrentSize(); i++) { if(book.equals(books.getBook(i))){ System.out.println("该图书已经存在,无法继续添加!"); return; } } books.addBook(book); books.setCurrentSize(books.getCurrentSize()+1); System.out.println("添加成功!"); } } }
b.删除图书
首先用户输入要删除的图书名称,然后在书架上进行查找,若能找到,标记图书所在位置,然后从此位置之后的一本书开始依次覆盖前一本书,然后将最后一个位置置为null,书架目前存放图书数目减一,否则找不到,无法删除。
public class DelBook implements Operate{ @Override public void work(Bookshelf books) { System.out.println("请输入要删除的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您要删除的图书"); }else{ for(int i= pos+1;i<books.getCurrentSize();i++){ Book book=books.getBook(i); books.modify(i-1,book); } books.modify(books.getCurrentSize(),null); books.setCurrentSize(books.getCurrentSize()-1); System.out.println("删除成功!"); } } }
c.显示图书
对书架进行遍历,依次输出每本图书信息。
public class DisplayBook implements Operate{ @Override public void work(Bookshelf books) { System.out.println("==============================================="); System.out.println("图书名称\t作者\t价格\t主题\t状态"); for(int i=0;i<books.getCurrentSize();i++){ System.out.println(books.getBook(i).toString()); } System.out.println("==============================================="); } }
d.查找图书
用户输入要查找的图书名称,然后对书架进行遍历,若找到则输出图书信息,否则书架上并未存放这本书。
public class FindBook implements Operate{ @Override public void work(Bookshelf books) { System.out.println("请输入要查找的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("该图书不存在"); }else{ System.out.println("==============================================="); System.out.println("图书名称\t作者\t价格\t主题\t状态"); System.out.println(books.getBook(pos).toString()); System.out.println("==============================================="); } } }
e.借阅图书
用户输入图书名称,然后对书架进行遍历,若能找到并且图书未借出,则将图书的状态置为true,表示借出,否则无法借阅。
public class BorrowBook implements Operate{ @Override public void work(Bookshelf books) { System.out.println("请输入要借阅的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您需要的图书"); }else{ if(books.getBook(pos).isBorrowed()==true){ System.out.println("该图书已经借出"); return; } books.getBook(pos).setBorrowed(true); System.out.println("借阅成功!"); } } }
f.归还图书
用户输入要归还的图书名称,然后在书架上依次进行遍历,找到要归还的图书,将图书的状态改为false,即为未借出,归还成功,若未找到,则不存在该图书,归还失败。
public class ReturnBook implements Operate { @Override public void work(Bookshelf books) { System.out.println("请输入要归还的图书名称"); Scanner sc=new Scanner(System.in); String name=sc.nextLine(); int pos=-1; for (int i = 0; i < books.getCurrentSize(); i++) { if(name.equals(books.getBook(i).getName())){ pos=i; break; } } if(pos==-1){ System.out.println("未找到您需要的图书"); }else{ books.getBook(pos).setBorrowed(true); System.out.println("归还成功!"); } } }
g.退出系统
即要退出循环,利用System.exit(0)正常退出。
public class ExitOpe implements Operate{ @Override public void work(Bookshelf books) { System.out.println("退出成功,欢迎下次使用!"); System.exit(0); } }
3、用户模块
a.User父类
定义一个用户的父类,定义了用户的姓名,以及包含操作的一个数组,还有菜单的抽象方法,以及封装了一个用户选择对应的操作类的方法。
public abstract class User { private String name; public Operate[] operates; public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public abstract int menu(); public void doWork(int option,Bookshelf books ){ this.operates[option].work(books); } }
b.管理员
继承User父类,重写菜单方法,在构造方法中,对操作数组进行相关定义。
public class Administrator extends User{ public Administrator(String name) { super(name); this.operates=new Operate[]{ new ExitOpe(), new AddBook(), new DelBook(), new DisplayBook(), new FindBook(), }; } @Override public int menu() { System.out.println("*******************************************"); System.out.println(" 1.添加图书 2.删除图书 "); System.out.println(" 3.显示图书 4.查找图书 "); System.out.println(" 0.退出系统 "); System.out.println("*******************************************"); System.out.println("请输入您的操作:"); Scanner sc = new Scanner(System.in); int option = sc.nextInt(); return option; } }
c.普通用户
继承User父类,重写菜单方法,在构造方法中,对操作数组进行相关定义。
public class RegularUser extends User{ public RegularUser(String name) { super(name); this.operates=new Operate[]{ new ExitOpe(), new BorrowBook(), new ReturnBook(), new DisplayBook(), new FindBook(), }; } @Override public int menu() { System.out.println("*******************************************"); System.out.println(" 1.借阅图书 2.归还图书 "); System.out.println(" 3.显示图书 4.查找图书 "); System.out.println(" 0.退出系统 "); System.out.println("*******************************************"); System.out.println("请输入您的操作:"); Scanner sc = new Scanner(System.in); int option = sc.nextInt(); return option; } }
4、主函数模块
需要定义一个登录方法,来判断是普通用户还是管理员,该方法返回的是User类,用到了向上转型,登录成功之后就可以进入对应菜单进行相关操作。
public class Main { public static User login() { System.out.println("欢迎来到图书管理系统"); System.out.println("请选择身份:1>管理员 2>普通用户"); Scanner sc = new Scanner(System.in); int option=sc.nextInt(); if(option!=1&&option!=2){ System.out.println("输入有误!"); } System.out.println("请输入姓名"); sc.nextLine(); String name=sc.nextLine(); System.out.println("欢迎"+name+",祝您使用愉快"); if (option==1){ return new Administrator(name); }else { return new RegularUser(name); } } public static void main(String[] args) { Bookshelf books = new Bookshelf(); User user=login(); while(true){ user.doWork(user.menu(),books); } } }
三、功能演示
管理员:
普通用户: