目录
一、分析需求
实现一个项目首先要搞清楚项目的功能有哪些:
图书馆管理系统首先要有书其次是书架,以及对书籍的一些操作。那么是谁对书籍进行操作呢?当然时我们这些普通用户以及对书籍进行管理的管理人员。
再展开分析:
1.书籍模块:一本书籍的基本信息有:书名,作者,价格,类别以及借阅状态。书籍的类别有·许多,一个书架放置一个类别的图书,这样比较方便查找书籍。
2.操作模块:查看全部书籍,查找某本书籍,借阅书籍,归还书籍,添加书籍,删除书籍,更新书籍信息。使用一个接口,具体功能到具体子类实现。这样假如增加一个书架,增删改查这些功能都是类似的,相同的代码就不用全部重写一遍~
3.用户模块:将对书籍的操作区分人员。普通用户对书籍的操作有:查看全部书籍,查找某本书籍,借阅和归还书籍。管理人员对书籍的操作有:查看全部书籍,查找某本书籍,添加书籍,删除书籍,更新书籍信息。
最后分析的结果如下图:
二、知识补充(关于List接口的使用)
Java中的数组都是定长数组,当书架上保存书籍时,书本的添加和删除就比较麻烦
因此使用JDK中的动态数组List接口(线性表)
ArrayList 动态数组实现以及一些常用方法:
public static void main(String[] args) {
// 创建一个保存整数的动态数组
// 要给这个动态数组中保存的类型,其中基本类型统一使用包装类
List<Integer> list = new ArrayList<>();
// 从尾部添加元素
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
// 遍历当前list集合
for (int temp : list) {
System.out.print(temp + " ");
}
System.out.println(list);
// 删除指定索引的元素
list.remove(1);
System.out.println(list);
// 修改索引为1的元素内容
list.set(1,300);
System.out.println(list);
// 查询索引为1的元素值
System.out.println(list.get(1));
// 查询当前list中是否包含指定值的内容
System.out.println(list.contains(300));
System.out.println(list.contains(100));
}
三、图书馆管理系统的实现
1. 先创建一个包以及包下的类
2. book包
2.1 Book类
(1)首先是书籍的基本信息(将属性设为私有,不允许类外随意访问)
private String bookName;//书名
private String author;//作者
private Double price;//价格
private String type;//类别
private Boolean isBorrowed;//借阅状态,false未借出,true借出
(2)其次,提供一个构造方法,在上架一本书时,我们要提供书籍的基本信息,isBorrowed刚上架时是未被借出去的,所以isBorrowed默认是false
温馨提示:Alt + insert 快捷生成构造方法,setter,getter,以及toString方法哦
public Book(String name, String author, Double price, String type) {
this.bookName = name;
this.author = author;
this.price = price;
this.type = type;
this.isBorrowed = false;
}
(3)然后,提供setter和getter方法获取和修改书籍的基本信息。(书籍的名字是不能修改的,因此不提供bookName的setter方法)
public void setAuthor(String author) {
this.author = author;
}
public void setPrice(Double price) {
this.price = price;
}
public void setType(String type) {
this.type = type;
}
public void setBorrowed(Boolean borrowed) {
isBorrowed = borrowed;
}
public String getBookName() {
return bookName;
}
public String getAuthor() {
return author;
}
public Double getPrice() {
return price;
}
public String getType() {
return type;
}
public Boolean getBorrowed() {
return isBorrowed;
}
(4)最后是使用toString方法打印输出一本书的基本信息。
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
", isBorrowed=" + isBorrowed +
'}';
}
2.2 BookList类
图书馆的书籍都放在这里~
(1)需要有个书籍的数组,来存放当前书架上的所有书籍Book~
//存放所有具体的书本对象
public static final List<Book> books = new ArrayList<>();
(2)需要保存当前书架上所有书籍名称的列表,以便于查询~
// 保存当前所有书的名称
private static final List<String> bookNames = new ArrayList<>();
(3)需要一个静态方法体提供图书馆里的默认藏书~
// 在类加载时,将静态变量初始化,相当于图书馆默认藏书
static {
books.add(new Book("三国演义","罗贯中",70.0,"小说"));
books.add(new Book("西游记","施耐庵",60.0,"小说"));
books.add(new Book("水浒传","吴承恩",78.0,"小说"));
books.add(new Book("红楼梦","曹雪芹/无名氏",68.0,"小说"));
bookNames.add("三国演义");
bookNames.add("西游记");
bookNames.add("水浒传");
bookNames.add("红楼梦");
}
(4)需要一个int型成员变量,记录书架上书籍的个数,同时提供setter和getter方法修改和获取书籍的数量~
private int booksNum = 4;
public void setBooksNum(int booksNum) {
this.booksNum = booksNum;
}
public int getBooksNum() {
return booksNum;
}
(5)关于书本的增删改查实际上就是在书架对象上进行操作的~
这里到后面实现增删改查再慢慢补充。
3. operation包
3.1 IOperation接口
实现对动态数组的操作~
Scanner scanner = new Scanner(System.in);
void doWork(BookList booklist);//具体操作到具体子类实现
3.2 AddOperation类
添加书籍
(1)首先是继承IOperation接口
public class AddOperation implements IOperation
(2)然后是重写接口的doWork方法
温馨提示:Alt + insert 快捷重写方法哦
@Override
public void doWork(BookList booklist) {
System.out.println("这里是添加书籍操作哦!");
}
先做好前期基础的准备工作,搭好框架,后面一点一点实现,才能发现程序错误出现在哪~
3.3 BorrowOperation类以及其他操作的类
和上面AddOperation类一样继承IOperation接口,搭好框架后面再实现具体操作
//DeleteOperation等类也是这样,继承接口哦
public class BorrowOperation implements IOperation
@Override
public void doWork(BookList booklist) {
System.out.println("这里是借阅书籍操作哦!");
}
后面的几个操作类也是如此,这里就不重复啦
4. user包
4.1 User类
抽象类User类是AdminUser和NormalUser类的父类,存储一些AdminUser和NormalUser类的共有信息。
(1)首先是成员变量userName,以及它的构造方法,setter和getter方法
public abstract class User {
protected String userName;
public User(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
(2)其次是菜单,不同用户的菜单不一样,这里具体的菜单到子类实现。
public abstract int menu();//菜单,根据用户输入返回具体方法
(3)根据用户的输入,选择对应的操作,在对应的书架上完成
protected IOperation[] operations;
public void doOperation(int choice,BookList booklist){
operations[choice - 1].doWork(booklist);
}
4.2 NormalUser类
(1)首先是继承父类User
public class NormalUser extends User
(2)从键盘输入选择
private Scanner scanner= new Scanner(System.in);
(3)重写父类方法,打印菜单以及userNAme的setter和getter方法
@Override
public int menu() {
System.out.println("======================================");
System.out.println("欢迎用户" + this.userName + "登录图书馆管理系统");
System.out.println("1.显示书籍列表");
System.out.println("2.查询书籍");
System.out.println("3.借阅书籍");
System.out.println("4.归还书籍");
System.out.println("-1.退出系统");
System.out.println("请输入您的选择:");
int choice = scanner.nextInt();
System.out.println("======================================");
if(choice == -1){
scanner.close();
}
return choice;
}
public NormalUser(String userName) {
super(userName);
}
@Override
public String getUserName() {
return super.getUserName();
}
@Override
public void setUserName(String userName) {
super.setUserName(userName);
}
(4)NormalUser类的构造方法,用户的选择 choice- 1 为数组operations的下标,对应一个对书籍的操作。
public NormalUser(String userName) {
super(userName);
super.operations = new IOperation[] {
new ListBooksOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
4.3 AdminUser类
1)首先是继承父类User
public class NormalUser extends User
(2)从键盘输入选择
private Scanner scanner= new Scanner(System.in);
(3)重写父类方法,打印菜单以及userNAme的构造方法、setter和getter方法
@Override
public int menu() {
System.out.println("======================================");
System.out.println("欢迎管理员" + this.userName + "登录图书馆管理系统");
System.out.println("1.添加书籍");
System.out.println("2.删除书籍");
System.out.println("3.更新书籍");
System.out.println("4.查找书籍");
System.out.println("5.显示书籍列表");
System.out.println("-1.退出");
System.out.println("请输入您的选择:");
int choice = scanner.nextInt();
System.out.println("======================================");
if(choice == -1){
scanner.close();
}
return choice;
}
public AdminUser(String userName) {
super(userName);
}
@Override
public String getUserName() {
return super.getUserName();
}
@Override
public void setUserName(String userName) {
super.setUserName(userName);
}
(4)AdminUser类的构造方法
public AdminUser(String userName) {
super(userName);
super.operations = new IOperation[] {
new AddOperation(),
new DeleteOperation(),
new UpdateOperation(),
new FindOperation(),
new ListBooksOperation()
};
}
5. Main类
在LibraryManageSystem包下建一个Main的包,作为这个项目运行的入口,将程序跑起来!
(1)准备书籍
public static void main(String[] args) {
BookList booklist = new BookList();
}
(2)创建一个用户登录方法,区分普通用户和管理员
private static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的姓名:");
String userName = scanner.nextLine();
System.out.println("请输入您的身份:1表示普通用户,0表示管理员");
int who = scanner.nextInt();
if(who == 1){
return new NormalUser(userName);
} else{
return new AdminUser(userName);
}
}
(3)然后就是一直循环系统,用户不选择退出,系统就一直循环下去
public static void main(String[] args) {
BookList booklist = new BookList();
User user = login();
while (true){
int choice = user.menu();
if(choice == -1){
System.out.println("*****bye~*****");
break;
}
user.doOperation(choice,booklist);
}
}
好了,这时候框架差不多搭建好了,现在看看程序跑起来成什么样:
运行Main程序:
(1)普通用户登录
(2)管理员登录
程序跑起来没有出问题后,我们来实现具体的操作。
6. operation包下具体操作的实现
6.1 ListBooksOperation类
(1)首先在BookList类中添加displayAllBooks方法遍历当前所有图书信息
public void displayAllBooks() {
// 遍历当前所有图书信息 - 即遍历books数组
for (Book book : books) {
System.out.println(book);
}
}
(2)实现ListBooksOperation类
@Override
public void doWork(BookList booklist) {
System.out.println("您正在执行的是查询书籍列表操作");
// 书本信息存放在书架上
booklist.displayAllBooks();
System.out.println("查询书籍列表操作完成");
}
6.2 AddOperation类
(1)首先在BookList类中添加isBookContains方法使用Java中的contains方法查询是否存在这本书
public boolean isBookContains(String bookName) {
return bookNames.contains(bookName);
}
(2)在BookList类中添加addBook方法在书架上上架这本书
public void addBook(Book book) {
// 在books数组中添加该书本
books.add(book);
// 同时更新书籍名称数组
bookNames.add(book.getBookName());
}
(3)实现AddOperation类
先查找是否已经存在这本书,这本书存在的话就不用重复添加了
@Override
public void doWork(BookList booklist) {
//System.out.println("添加书籍");
System.out.println("您现在进行的是添加书籍操作");
System.out.println("请输入您要添加的书本名称");
String bookName = scanner.nextLine();
// 判断当前书架上是否已经包含了该图书
if (booklist.isBookContains(bookName)) {
System.out.println("该书籍已经存在,无须重复添加!");
return;
}
// 说明当前书架上并不包含该书,添加书籍的其他信息
System.out.println("请输入作者名称");
String author = scanner.nextLine();
System.out.println("请输入书本的类型");
String type = scanner.nextLine();
System.out.println("请输入书本价格");
double price = scanner.nextDouble();
Book book = new Book(bookName,author,price,type);
// 在书架上上架该书
booklist.addBook(book);
int num = booklist.getBooksNum();
booklist.setBooksNum(num + 1);
System.out.println("书本已添加!");
}
查看一下代码能不能正常跑起来,得到我们想要的结果:
6.3 BorrowOperation类
(1)在BookList类中添加getBooks方法获取一本书的基本信息
// 获取一本书
public Book getBooks(String bookName){
for (Book book:books
) {
if (book.getBookName().equals(bookName)) {
return book;
}
}
return null;
}
(2)实现BorrowOperation类
@Override
public void doWork(BookList booklist) {
System.out.println("您现在进行的是借阅书籍操作");
System.out.println("请输入您要借阅的书本名称");
String bookName = scanner.nextLine();
// 查询是否存在这本书
if (!booklist.isBookContains(bookName)) {
System.out.println("该书籍还未上架,请借阅其他书籍");
return;
}
// 获取这本书,并且这本书是未借出的
if (!booklist.getBooks(bookName).equals("null") && !booklist.getBooks(bookName).getBorrowed()){
// 将isBorrowed属性改为true
booklist.getBooks(bookName).setBorrowed(true);
System.out.println("借阅成功!");
}else {
System.out.println("该书籍已经借出去!!!");
}
}
运行一下:
6.4 DelateOPeration类
(1)在BookList类中添加daleteBooks方法删除一本书
// 删除一本书
public boolean deleteBooks(String bookName){
for (Book book:books
) {
if (book.getBookName().equals(bookName)) {
books.remove(book);
return true;
}
}
return false;
}
(2)实现BorrowOperation类
@Override
public void doWork(BookList booklist) {
System.out.println("您现在进行的是删除书籍操作");
System.out.println("请输入您要删除的书本名称");
String bookName = scanner.nextLine();
// 判断当前书架上是否已经包含了该图书
if (!booklist.isBookContains(bookName)) {
System.out.println("该书籍不存在!");
return;
}
// 删除书籍
if (booklist.deleteBooks(bookName)){
System.out.println("书籍删除成功!");
}else {
System.out.println("书籍删除失败!");
}
}
运行一下:
6.5 FindOperation类
@Override
public void doWork(BookList booklist) {
System.out.println("您现在进行的是查找书籍操作");
System.out.println("请输入您要查找的书本名称");
String bookName = scanner.nextLine();
// 判断当前书架上是否已经包含了该图书
if (!booklist.isBookContains(bookName)) {
System.err.println("该书籍不存在!");
return;
}
// 获取一本书,使用toString方法打印输出
Book book = booklist.getBooks(bookName);
System.out.println(book.toString());
}
运行一下:
6.6 ReturnOPeration类
@Override
public void doWork(BookList booklist) {
System.out.println("您现在进行的是归还书籍操作");
System.out.println("请输入您要归还的书本名称");
String bookName = scanner.nextLine();
// 判断当前书架上是否已经包含了该图书
if (!booklist.isBookContains(bookName)) {
System.out.println("未找到名为“" + bookName + "”的书籍,请确认书籍名称正确后再归还");
return;
}
// 获取这本书,并且这本书是已经借出的
if (!booklist.getBooks(bookName).equals("null") && booklist.getBooks(bookName).getBorrowed()){
// 将isBorrowed属性改为false
booklist.getBooks(bookName).setBorrowed(false);
System.out.println("归还成功!");
}else {
System.out.println("归还失败!!!");
}
}
运行一下:
6.7 UdateOperation 类
@Override
public void doWork(BookList booklist) {
System.out.println("您现在进行的是更新书籍信息操作");
System.out.println("请输入您要更新的书本名称");
String bookName = scanner.nextLine();
// 判断当前书架上是否已经包含了该图书
if (!booklist.isBookContains(bookName)) {
System.err.println("该书籍不存在!");
return;
}
// 更新该书本的信息
Book book = booklist.getBooks(bookName);
System.out.println("请输入作者名称");
String author = scanner.nextLine();
book.setAuthor(author);
System.out.println("请输入书本的类型");
String type = scanner.nextLine();
book.setType(type);
System.out.println("请输入书本价格");
double price = scanner.nextDouble();
book.setPrice(price);
System.out.println("书本信息已更新!");
}
运行一下:
到这里,图书馆管理系统的全部代码已经实现了
四、成品
我的成品代码放这里啦~https://gitee.com/dragon-yushuang/javase_code/tree/master/src/LibraryManageSystem