一、简介
图书管理小系统,主要利用 JavaSE 所学到的知识点:类、抽象类、封装、继承、多态、接口等进行一个简单的代码练习。
二、核心需求
1. 简单的登录
2. 管理端
- 整理书籍
- 查阅图书
- 增加图书
- 删除图书
- 打印图书列表
- 退出系统
3. 用户端
- 查询书籍
- 借阅书籍
- 归还书籍
- 退出
三、项目文件列表
四、类的设计
1. 创建图书相关的类
创建 Book 类,表示一本书
//图书 book 实体类
public class Book {
//创建字段
private String name; //书名
private String author; //作者
private String price; //价格
private String type; //图书类型
private boolean isBorrowed; //是否借出
//构造方法,是否借出不需要初始化,默认未借出
public Book(String name, String author, String price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}
//常规 get/set 方法
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 getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isBorrowed() {
return isBorrowed;
}
public void setBorrowed(boolean borrowed) {
isBorrowed = borrowed;
}
//字段输出打印
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price='" + price + '\'' +
", type='" + type + '\'' +
((isBorrowed == true) ? "已借出" : "未借出") +
'}';
}
}
创建 BookList 类,用来保存 N 本书
//存储图书信息的顺序表
public class BookList {
//表示存储信息个数
private int usedSize;
//存储图书信息的顺序表,初始化容量为 10
private Book[] books = new Book[10];
//构造方法,初始化一些图书信息
public BookList(){
this.books[0] = new Book("校花的贴身高手","鱼人二代","199","网络小说");
this.books[1] = new Book("盘龙","爱吃西红柿","89","网络小说");
this.books[2] = new Book("三国演义","罗贯中","99.9","四大名著");
this.books[3] = new Book("红楼梦","曹雪芹","99.9","四大名著");
//记录图书信息个数变量
usedSize += 4;
}
//封装成员变量提供给外界的方法,设置已经存储图书个数
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
//找到顺序表中第 i 条数据
public Book getPos(int i){
return books[i];
}
//在 pos 位置添加图书数据
public void setBooks(int pos, Book book){
books[pos] = book;
}
}
2. 创建操作相关的类
创建接口 IOPeration
//operation文件夹下的操作类都要使用到的work
//对图书顺序表进行增删改查的操作
public interface IOPeration {
void work(BookList bookList);
}
接下来创建一组操作类,每个类对应一个用户的动作
AddOperation
DelOperation
FindOperation
RemoveOperation
DisplayOperation
BorrowOperation
ReturnOperation
ExitOperation
先把空类创建好,实现 IOPeration,不着急实现细节
抽象出 Operation 的好处:让操作和操作之间低耦合,让操作和用户之间低耦合
3. 创建用户相关的类
创建 User 类,这是一个抽象类
public abstract class User {
//开放给子类的成员变量
protected String name;
//使用操作类的接口
//用来作为存储用户选择的类型,方便之后去进行功能操作
protected IOPeration[] ioPerations;
public User(String name) {
this.name = name;
}
//用户菜单抽象类
public abstract int menu();
//根据用户选择choice,到顺序表bookList中操作功能work方法
public void doOperation(int choice, BookList bookList){
this.ioPerations[choice].work(bookList);
}
}
创建普通用户类,是 User 的子类
//普通用户类
public class NormalUser extends User {
//构造方法中,接口数组存储好了当前用户类型能选择的操作
public NormalUser(String name) {
super(name);
//数组下标已经和用户的选择对应好了
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new BorrowOperation(),
new ReturnOperation()
};
}
//普通用户的菜单类
@Override
public int menu() {
System.out.println("=============== 普通用户菜单 ===============");
System.out.println("hello " + this.name + ",欢迎来到图书管理系统");
System.out.println("1. 查找图书");
System.out.println("2. 借阅图书");
System.out.println("3. 归还图书");
System.out.println("0. 退出系统");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
return choice;
}
}
创建管理员用户类
//管理员类
public class AdiminUser extends User {
public AdiminUser(String name) {
super(name);
//接口数组存储好了当前用户类型能选择的操作
this.ioPerations = new IOPeration[]{
new ExitOperation(),
new FindOperation(),
new AddOperation(),
new DelOperation(),
new DisplayOperation()
};
}
//管理员特有的菜单类
@Override
public int menu() {
System.out.println("=============== 管理员菜单 ===============");
System.out.println("hello " + this.name + ",欢迎来到图书管理系统");
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 = scanner.nextInt();
return choice;
}
}
4. 进行整合
创建 Main 类和 main 方法,搭建整体逻辑
public class Main {
//登录方法
public static User login(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名: ");
String name = scanner.nextLine();
System.out.println("请输入你的身份: 1(管理员) 2(普通用户)");
int choice = scanner.nextInt();
//多态,根据用户选择而创建相应的用户类型
if (choice == 1) {
return new AdiminUser(name);
}else {
return new NormalUser(name);
}
}
//测试类
/*
存储图书的顺序表,通过无参的构造方法生成;
通过login方法和user动态绑定用户类型;
取决于user引用的对象来调用菜单得到操作的选项;
将操作的选项choice和存储数据的顺序表bookList传递给doOperation方法。
doOperation方法已经准备好ioPerations数组,等待choice来调用work方法工作。
*/
public static void main(String[] args) {
//生成顺序表
BookList bookList = new BookList();
//根据用户的选择创建相应的用户类
User user = login();
while (true) {
//用户从菜单,选择要操作的功能
int choice = user.menu();
//根据选择choice对顺序表bookList操作。
user.doOperation(choice, bookList);
}
}
}
可以测试一下,系统框架是否存在问题。
ps. 项目的框架一般是架构师来搭建,接下来的功能模块才是普通程序员干的事。
5. 实现具体的每个 Operation
其实就是操作顺序表数据
添加图书类
//添加图书类
public class AddOperation implements IOPeration {
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入图书的名字:");
String name = scanner.nextLine();
System.out.println("请输入图书的作者:");
String author = scanner.nextLine();
System.out.println("请输入图书的类型:");
String type = scanner.nextLine();
System.out.println("请输入图书的价格:");
String price = scanner.nextLine();
//将用户填入的数据,存储到 Book 类中
Book book = new Book(name,author,type,price);
//获取顺序表有效数据长度
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
//自定义的方法,根据 i 获取顺序表中图书数据
Book book1 = bookList.getPos(i);
if (book1.getName().equals(name)) {
System.out.println("该图书系统已经存在!");
return;
}
}
//自定义方法,在 size 位置添加图书信息 book
bookList.setBooks(size, book);
//添加成功,顺序表有效数据长度 + 1
bookList.setUsedSize(size+1);
System.out.println("添加图书成功!");
}
}
借阅图书类
public class BorrowOperation implements IOPeration {
@Override
public void work(BookList bookList) {
System.out.println("借阅图书");
System.out.println("请输入要借阅的图书名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
if (bookList.getPos(i).getName().equals(name) && (book.isBorrowed() == false)) {
bookList.getPos(i).setBorrowed(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("没找到 " + name + " 这本书");
}
}
删除图书类
public class DelOperation implements IOPeration {
@Override
public void work(BookList bookList) {
System.out.println("删除图书!");
System.out.println("请输入您要删除的图书名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int size = bookList.getUsedSize();
int pos = -1;
for (int i = 0; i < size; i++){
Book book = bookList.getPos(i);
if (book.getName().equals(name)) {
pos = i;
break;
}
}
if (pos != -1) {
for (int i = pos; i < size-1; i++){
//获取下一个位置的图书数据,添加到前一个位置。
Book book = bookList.getPos(i+1);
bookList.setBooks(i,book);
}
//顺序表有效数据减一
bookList.setUsedSize(size-1);
System.out.println("删除成功!");
return;
}
System.out.println("删除失败!");
}
}
显示图书类
public class DisplayOperation implements IOPeration {
@Override
public void work(BookList bookList) {
if (bookList.getUsedSize() == 0){
System.out.println("目前系统没有图书");
return;
}
System.out.println("打印所有图书~");
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
System.out.println(book);
}
}
}
退出系统类
public class ExitOperation implements IOPeration {
@Override
public void work(BookList bookList) {
System.out.println("退出系统!");
System.exit(0);
}
}
查找图书类
public class FindOperation implements IOPeration {
@Override
public void work(BookList bookList) {
System.out.println("查找图书~");
System.out.println("请输入书名:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
if (book.getName().equals(name)) {
System.out.println("找到了");
//找到了,输出 book 数据,会自动调用 toString 方法
System.out.println(book);
return;
}
}
System.out.println("系统中没有这本书~");
}
}
归还图书类
public class ReturnOperation implements IOPeration {
@Override
public void work(BookList bookList) {
System.out.println("归还图书~");
System.out.println("请输入您要归还的图书名字:");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
int size = bookList.getUsedSize();
for (int i = 0; i < size; i++) {
Book book = bookList.getPos(i);
if (name.equals(book.getName()) && (book.isBorrowed() == true)) {
book.setBorrowed(false);
System.out.println("图书归还成功!");
return;
}
}
System.out.println("图书归还失败!");
}
}