一、系统整体设计:分层与职责划分
一个良好的系统设计首先要明确模块边界和职责。本图书管理系统采用模块化分层设计,将代码按功能划分为5个核心包,每个包承担独立职责,避免代码耦合。
系统模块结构
包名(Package) | 核心类/接口 | 职责描述 |
---|---|---|
Book | Book 、BookList | 封装图书数据(Book )和书架管理(BookList ) |
User | User (抽象)、AdminUser 、NormalUser | 封装用户信息,区分管理员和普通用户的不同权限 |
IOperations | IOperation (接口)、各操作类 | 定义所有业务操作的标准接口,实现具体功能(查找、新增、借阅等) |
根包 | Main | 系统入口,负责用户登录、流程控制 |
二、核心模块详解:从数据到功能
1. Book包:数据封装
Book
包是系统的“数据层”,负责存储图书信息和管理书架,核心是封装思想的体现——将数据(图书属性)和操作(get/set方法)封装在类内部,对外暴露安全的访问接口。
1.1 Book类:图书实体
Book
类代表一本图书,包含5个核心属性,通过private
修饰保证数据安全,通过getter/setter
提供访问入口,并重写toString()
方便打印图书信息。
public class Book {
// 私有属性:保证数据不被外部直接修改
private String name; // 书名(唯一标识)
private String author; // 作者
private int price; // 价格
private String type; // 类型
private boolean isBorrowed; // 借阅状态
// 构造方法:初始化图书信息(借阅状态默认false,即未借出)
public Book(String name, String author, int price, String type) {
this.name = name;
this.author = author;
this.price = price;
this.type = type;
this.isBorrowed = false; // 初始未借出
}
// getter/setter:对外提供安全的访问接口
public boolean isBorrowed() { return isBorrowed; }
public void setBorrowed(boolean borrowed) { isBorrowed = borrowed; }
// 其他getter/setter省略...
// 重写toString:自定义图书打印格式(包含借阅状态)
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", type='" + type + '\'' +
((isBorrowed)?", 已借出":", 未借出")+ // 动态显示借阅状态
'}';
}
}
1.2 BookList类:书架管理
BookList
类相当于“书架”,管理一个Book
数组,并记录有效图书数量(usedSize
)。它提供了图书的增删查改入口,是数据操作的“中间层”。
核心逻辑:
- 初始化时默认添加3本经典小说(《三国演义》《西游记》《红楼梦》);
- 通过
setBook()
和getBook()
操作指定位置的图书; - 通过
getUsedSize()
和setUsedSize()
管理有效图书数量,避免数组越界。
public class BookList {
private Book[] books = new Book[10]; // 固定大小的书架(最多10本)
private int usedSize; // 有效图书数量(避免遍历空位置)
// 构造方法:初始化默认图书
public BookList(){
books[0] = new Book("三国演义","罗贯中",10,"小说");
books[1] = new Book("西游记","吴承恩",59,"小说");
books[2] = new Book("红楼梦","曹雪芹",16,"小说");
this.usedSize = 3; // 初始3本有效图书
}
// 对外提供书架操作接口
public Book getBook(int pos) { return books[pos]; }
public void setBook(Book book, int pos) { this.books[pos] = book; }
public int getUsedSize() { return usedSize; }
public void setUsedSize(int usedSize) { this.usedSize = usedSize; }
}
2. User包:多态的核心体现
User
包是系统的“用户层”,通过抽象类+子类的结构实现多态,让不同用户(管理员/普通用户)拥有不同的菜单和操作权限,而无需修改核心流程。
2.1 User抽象类:用户模板
User
类被定义为抽象类,它不直接实例化,而是作为所有用户的“模板”,定义通用属性(name
)和抽象方法(menu()
),并通过IOperation[]
存储当前用户可执行的操作。
public abstract class User {
protected String name; // 用户名
// 存储当前用户可执行的操作(多态的关键:子类初始化不同操作数组)
protected IOperation[] iOperations;
// 构造方法:初始化用户名
public User(String name) { this.name = name; }
// 抽象方法:不同用户的菜单不同,由子类实现
public abstract int menu();
// 统一执行操作:通过操作数组索引调用对应操作(解耦流程与具体功能)
public void doIOperations(int ch, BookList bookList) {
iOperations[ch].work(bookList);
}
}
2.2 AdminUser:管理员子类
管理员拥有最高权限,可执行“查找、新增、删除、显示、退出”5个操作。核心逻辑:
- 构造方法中初始化
iOperations
数组,顺序对应菜单选项; - 实现
menu()
方法,打印管理员专属菜单并返回用户选择。
public class AdminUser extends User {
// 初始化管理员可执行的操作(索引0=退出,1=查找,2=新增,3=删除,4=显示)
public AdminUser(String name) {
super(name);
this.iOperations = new IOperation[]{
new ExitOperation(), // 0.退出
new FindOperation(), // 1.查找
new AddOperation(), // 2.新增
new DelOperation(), // 3.删除
new ShowOperation() // 4.显示
};
}
// 管理员菜单:返回用户选择的操作索引
@Override
public int menu() {
System.out.println("欢迎 " + name + " 来到图书管理系统");
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("请输入你的选择:");
return new Scanner(System.in).nextInt();
}
}
2.3 NormalUser:普通用户子类
普通用户权限有限,仅可执行“查找、借阅、归还、退出”4个操作。逻辑与管理员类似,但iOperations
数组和菜单选项不同。
public class NormalUser extends User {
// 初始化普通用户可执行的操作(索引0=退出,1=查找,2=借阅,3=归还)
public NormalUser(String name) {
super(name);
this.iOperations = new IOperation[]{
new ExitOperation(), // 0.退出
new FindOperation(), // 1.查找
new BorrowOperation(), // 2.借阅
new ReturnOperation() // 3.归还
};
}
// 普通用户菜单
@Override
public int menu() {
System.out.println("欢迎 " + name + " 来到图书管理系统");
System.out.println("*****普通用户菜单******");
System.out.println("1.查找图书");
System.out.println("2.借阅图书");
System.out.println("3.归还图书");
System.out.println("0.退出");
System.out.println("请输入你的选择:");
return new Scanner(System.in).nextInt();
}
}
3. IOperations包:接口解耦业务功能
IOperations
包是系统的“功能层”,通过接口定义所有业务操作的标准,让具体功能(如查找、借阅)与用户流程解耦——新增功能时只需实现接口,无需修改现有代码(符合开闭原则)。
3.1 IOperation接口:操作标准
IOperation
接口定义了一个抽象方法work(BookList bookList)
,所有业务操作类都必须实现该方法,保证操作的“统一性”。
public interface IOperation {
// 所有操作的统一入口:接收BookList对象,操作书架数据
void work(BookList bookList);
}
3.2 核心操作类实现(示例)
以“查找图书”和“借阅图书”为例,展示具体功能的实现逻辑:
(1)FindOperation:查找图书
逻辑:接收用户输入的书名,遍历书架匹配,找到则打印图书信息,未找到则提示。
public class FindOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("查找图书...");
System.out.println("输入待查找的书名:");
String name = new Scanner(System.in).nextLine();
// 遍历有效图书(仅遍历usedSize个,避免空指针)
for (int i = 0; i < bookList.getUsedSize(); i++) {
Book book = bookList.getBook(i);
if (book.getName().equals(name)) {
System.out.println(book); // 调用Book的toString()
return;
}
}
System.out.println("该图书不存在");
}
}
(2)BorrowOperation:借阅图书
逻辑:匹配书名后,先判断图书是否已借出,未借出则修改isBorrowed
状态为true
,已借出则提示。
public class BorrowOperation implements IOperation {
@Override
public void work(BookList bookList) {
System.out.println("借阅图书...");
System.out.println("输入待借阅书名:");
String name = new Scanner(System.in).nextLine();
for (int i = 0; i < bookList.getUsedSize(); 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("未找到" + name);
}
}
其他操作类(如AddOperation
新增、DelOperation
删除)逻辑类似,均围绕“用户输入→数据校验→操作书架”的流程实现,此处不再赘述。
三、系统入口:Main类的流程控制
Main
类是系统的“控制层”,负责串联所有模块,核心流程分为3步:
1. 初始化书架
创建BookList
对象,自动加载3本默认图书。
BookList bookList = new BookList();
2. 用户登录
接收用户名和身份(管理员/普通用户),返回对应的User
子类对象(向上转型,多态的前提)。
public static User login() {
Scanner scan = new Scanner(System.in);
System.out.println("你的姓名:");
String name = scan.nextLine();
System.out.println("请输入你的身份:1.管理员 2.普通用户");
int ch = scan.nextInt();
if (ch == 1) {
return new AdminUser(name); // 向上转型为User
} else {
return new NormalUser(name); // 向上转型为User
}
}
3. 循环执行操作
通过while(true)
实现循环菜单,核心是多态调用:
user.menu()
:根据实际用户类型(管理员/普通)调用对应菜单;user.doIOperations()
:根据用户选择的索引,调用对应操作。
public static void main(String[] args) {
BookList bookList = new BookList();
User user = login(); // 向上转型:User指向AdminUser/NormalUser
while (true) {
int choice = user.menu(); // 多态:调用子类的menu()
user.doIOperations(choice, bookList); // 多态:调用对应操作
}
}
四、系统亮点:面向对象思想的落地
这个图书管理系统的核心价值,在于将面向对象的三大特性和设计原则融入实际开发:
1. 封装性
Book
类隐藏图书属性,通过getter/setter
控制访问;BookList
类隐藏数组操作,对外提供安全的书架管理接口。
2. 继承与多态
User
抽象类定义通用行为,子类(AdminUser
/NormalUser
)实现差异化功能;- 向上转型(
User user = new AdminUser()
)让代码无需区分用户类型,直接调用通用方法(menu()
/doIOperations()
)。
3. 接口解耦(开闭原则)
- 新增功能时(如“修改图书信息”),只需新建类实现
IOperation
接口,无需修改User
或Main
的代码; - 不同用户的权限调整,只需修改
iOperations
数组的元素顺序,无需改动操作类本身。
五、扩展建议:让系统更完善
当前系统已实现核心功能,但仍有优化空间,可作为后续扩展方向:
- 书架扩容:将
Book[]
改为ArrayList<Book>
,支持动态扩容; - 用户密码验证:在
login()
中增加密码输入和校验(可存储在数组或文件中); - 图书ID唯一标识:避免书名重复导致的操作错误(如两本《西游记》);
- 数据持久化:用IO流将图书信息存储到文件(如
books.txt
),避免程序重启后数据丢失; - 异常处理:增加
try-catch
捕获用户输入错误(如输入非数字的菜单选项)。