一、整体框架
我们采取面向对象的编程思想,将整个图书管理系统抽象出多个对象,然后通过各个对象之间的交互来完成我们的整体设计需求
我们整体的设计框架如下图:
对于不同的板块,我们分成3个包,一个关于书籍,一个关于用户,一个关于操作
- 书籍是放在书架上的,因此他们放在同一个包内
- 用户分为普通用户和管理员用户,他们都是对系统进行操作的人,所以放在同一个包内
- 操作包内都是用户对系统进行操作的功能
对应我们上述结构图我们如下设计:
二.书籍和书架
书籍(Book)
我们应该提供书籍的相关信息:
- 书名
- 作者
- 价格
- 书籍类型
- 借阅状态
为了体现面向对象的封装特性,我们将这些字段信息设为private,然后在通过set和get方法来实现对其进行访问
package book;
public class Book {
private String name;
private String author;
private int price;
private String type;
private boolean isBorrowed;
public Book(String name, String author, int price, String type) {//构造函数初始化
this.name = name;
this.author = author;
this.price = price;
this.type = type;
}//构造函数为什么不初始化boolean呢? //因为boolean开始默认为false,在本系统中,我们认为flase为未借出, true为已借出
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 int getPrice() {
return price;
}
public void setPrice(int 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)
书架主要是用来存放书籍的,因此我们只需要提供以下俩个信息就可以:
- 已经存放的书籍,也就是一个书籍数组,数组中每一个元素都是一本书籍对象
- 已经存放的书籍的数量
为了体现面向对象的封装性,我们还是将这些字段信息设为private,然后再然后在通过set和get方法来实现对其进行访问
package book;
public class BookList {
private Book[] books=new Book[10];//存放书籍
private int countsize;//记录书架有多少本数
public BookList(){
this.books[0]=new Book("三国演义","罗贯中",28,"小说");
this.books[1]=new Book("西游记","吴承恩",33,"小说");
this.books[2]=new Book("红楼梦","曹雪芹",45,"小说");
this.countsize=3;//默认书架上已经存放了3本书
}
public int getUseSize(){
return countsize;
}
public void setUsedSize(int countsize){
this.countsize=countsize;
}
public Book getBook(int a){//获取某个位置的书架
return books[a];
}
public void setBook(int a,Book book){//设置某个位置的书籍
this.books[a]=book;
}
public Book[] getBooks(){
return books;
}
}
三.对书籍的相关操作
操作接口(IOperation)
所有的操作都是要对于书架进行操作的,所以我们在这里提供一个接口供不同操作来实现,并且给他们传入书架类的参数
package ioperations;
import book.BookList;
//操作接口
public interface Ioperation {
//我们然后增删查改的操作都是对于书架进行操作的,所以传入的参数是书架类
void work(BookList bookList);
}
首先将简单的操作来实现
退出系统(ExitOperation)
我们这里直接使用 exit 来结束整个程序就可以
package ioperations;
import book.BookList;
public class Exitoperation implements Ioperation{
@Override
public void work(BookList bookList) {
System.out.println("退出系统!");
System.exit(0);
}
}
展示图书(ShowOperation)
遍历整个书架,然后挨个打印输出图书信息就可以了
package ioperations;
import book.Book;
import book.BookList;
public class Showoperation implements Ioperation{
@Override
public void work(BookList bookList) {
int count=bookList.getUseSize();
for (int i = 0; i < count; i++) {
Book book=bookList.getBook(i);
System.out.println(book);
}
}
}
新增图书(AddOperation)
首先,我们需要让用户输入想要添加的图书的相关信息,然后我们为用户输入的图书新建一个对象,接下来就是合法性判断,我们拿刚才新建的图书对象和书架上的每一个图书对象进行遍历对比,如果没有重复的图书就可以存入这本书,要存入这本书就调用刚才书架类中提供的方法setBooks,在新加一本书籍后,对应的书籍数量也得增加,也就是调用setUesdSize方法来增加书籍的数量
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Addoperation implements Ioperation{
@Override
public void work(BookList bookList) {
//首先,先判断新书是否能够存放得下
int count=bookList.getUseSize();
if(count==bookList.getBooks().length){
System.out.println("书架已经满了,放不下了");
return;
}
//接着是构造对象
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("请输入价格:");
int price = scanner.nextInt();
Book newBook=new Book(name,author,price,type);
//接着是判断书架有没有这本书
for (int i = 0; i < count; i++) {
Book book=bookList.getBook(i);
if(book.getName().equals(name)){
System.out.println("书架已经有这本书了");
return;
}
}
//最后就是插入这本书
bookList.setBook(count,newBook);
bookList.setUsedSize(count+1);
System.out.println("这本书添加成功");
}
}
借阅图书(BorrowOperation)
首先,我们需要让用户输入想要添加的图书的相关信息,然后我们为用户输入的图书新建一个对象,然后我们挨个遍历书架上的书,如果有,那就可以借,将书籍的借阅状态改为true就可以,如果没有就告诉用户没有此书,无法借阅
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Borrowoperation implements Ioperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您想借的书籍名称:");
String name=scanner.nextLine();
int count =bookList.getUseSize();
for (int i = 0; i < count; i++) {//遍历书架查询
Book book=bookList.getBook(i);
if(book.getName().equals(name)){
if(book.isBorrowed()){
System.out.println("十分抱歉!这本书已经被借走了!");
return;
}
book.setBorrowed(true);
System.out.println("借阅成功!");
return;
}
}
System.out.println("十分抱歉!我们这没有您要借阅的书籍!");
}
}
删除图书(DeleteOperation)
首先,要删除图书的第一步应该是先找到这本书,因此我们像刚才借阅图书一样,先遍历整个书架找到这本书,然后记录这本书的位置,之后再利用书架提供的 setBooks 方法来存放这本书,如果没有找到那就告诉用户并且退出这个操作
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Deleteoperation implements Ioperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要删除的书籍名称:");
String name=scanner.nextLine();
int count=bookList.getUseSize();
int pos=-1;
int i=0;
//寻找这本书的位置
for (; i <count ; i++) {
Book book=bookList.getBook(i);
if(book.getName().equals(name)){
pos=i;
break;
}
}
//判断是否有这本书
if(i==count){
System.out.println("书架上没有您要删除的书籍!");
return;
}
//删除书籍
for (int j = pos; j <count-1 ; j++) {
Book book=bookList.getBook(j);
bookList.setBook(j,book);
}
bookList.setBook(count-1,null);
bookList.setUsedSize(count-1);
System.out.println("书籍删除成功!");
}
}
查找图书(FindOperation)
查找图书就非常简单了,我们在刚才的删除图书操作中相当于已经完成了这部分操作了
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Findoperation implements Ioperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您要寻找的书籍的名称:");
String name=scanner.nextLine();
int count=bookList.getUseSize();
for (int i = 0; i < count; i++) {
Book book=bookList.getBook(i);
if(book.getName().equals(name)){
System.out.println("找到这本书了!");
System.out.println(book);
return;
}
}
System.out.println("抱歉!书架上没有您要的书籍!");
}
}
归还图书(ReturnOperation)
和我们的借阅图书操作相同,唯一不同的就是这里是将图书的借阅状态改为 false
package ioperations;
import book.Book;
import book.BookList;
import java.util.Scanner;
public class Returnoperation implements Ioperation{
@Override
public void work(BookList bookList) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您要归还的书籍名称:");
String name=scanner.nextLine();
int count=bookList.getUseSize();
for (int i = 0; i < count; i++) {
Book book =bookList.getBook(i);
//判断是否为我们的书籍
if(book.getName().equals(name)){
if(book.isBorrowed()){
book.setBorrowed(false);
System.out.println("书籍归还成功!");
return;
}
}
}
System.out.println("抱歉!您要归还的书籍不是我们的");
}
}
四.用户部分
用户抽象类(User)
在普通用户和管理员用户中存在许多共性,因此我们这里设置一个抽象类供普通用户和管理员用户来继承使用
package user;
import book.BookList;
import ioperations.Ioperation;
public abstract class User {
protected String name;//姓名
public Ioperation[] ioperations;//操作接口数组
public User(String name){
this.name=name;
}
public abstract int menu();//菜单
//供用户来选择操作,调用操作接口
public void doIoperation(int count, BookList bookList){
ioperations[count].work(bookList);
}
}
管理员类(MasterUser)
我们设置管理用户的菜单,再对应着菜单设置接口类型的数组的具体操作
package user;
import ioperations.*;
import java.util.Scanner;
public class MasterUser extends User{
public MasterUser(String name) {
super(name);
this.ioperations=new Ioperation[]{//初始化接口数组
new Exitoperation(),
new Findoperation(),
new Addoperation(),
new Deleteoperation(),
new Showoperation()
};
}
@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. 退出系统");
System.out.println("**********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的操作:");
int choice = scanner.nextInt();
return choice;
}
}
普通用户(NormalUser)
和管理员用户的设置一样,我们对应的存放接口数组中的操作就可以
package user;
import ioperations.*;
import java.util.Scanner;
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("1. 查找图书");
System.out.println("2. 借阅图书");
System.out.println("3. 归还图书");
System.out.println("0. 退出系统");
System.out.println("**********************");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你想办理的业务:");
int choice = scanner.nextInt();
return choice;
}
}
五、Main实现
import book.BookList;
import user.MasterUser;
import user.NormalUser;
import user.User;
import java.util.Scanner;
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 MasterUser(name);
}else{
return new NormalUser(name);
}
}
public static void main(String[] args) {
BookList bookList=new BookList();
User user=login();
while(true){
int choice= user.menu();
user.doIoperation(choice,bookList);
}
}
}
Main的实现是以上内容比较难理解的,接下来将用一张流程图来解释:
感谢您的耐心阅读!谢谢!