图书管理系统主干类为book、reader、borrowrecord和library,各司其职:book管理自身状态与可用性,reader管控借阅配额,borrowrecord封装借期与罚金计算,library仅协调调度,通过组合与协议实现松耦合与高内聚。

用最纯粹的面向对象思维设计图书管理系统,核心不是堆砌类或套用语法,而是让每个类真正“像一个活生生的角色”——有明确身份、清晰职责、自主行为,并只和它该打交道的对象说话。
聚焦真实世界角色,拒绝技术名词建模
别一上来就写 BookRepository 或 IBorrowService。先问:系统里有哪些能独立做事的“人”或“物”?答案很朴素:书(Book)、读者(Reader)、借阅这件事本身(BorrowRecord)、以及负责协调的图书馆(Library)。这四个就是主干类,其他全是它们的延伸或辅助。
比如“借书”不是 Library 调用一堆方法,而是 Reader 主动向 Library 请求借某本 Book;Library 判断规则后,生成一条 BorrowRecord —— 这条记录自己知道怎么算逾期、怎么算罚款,不靠别人告诉它。
每个类管好自己的状态和规则,不越界
高内聚的关键,在于把业务规则锁死在对应类内部:
-
Book 知道自己能不能被借(
isAvailable())、借出/归还时如何更新状态(borrow()/return()),但不管“谁来借”或“借多久” -
Reader 知道自己最多能借几本(
maxBorrow)、当前借了几本(borrowedBooks.size())、能否再借(canBorrow()),但不管图书库存或逾期逻辑 -
BorrowRecord 知道自己的借期、应还日、是否已逾期(
isOverdue())、按天算罚金(getFine()),所有时间与金额计算全由它自己完成 - Library 不存数据,只做调度:接收 Reader 的请求 → 查 Book 状态 → 查 Reader 配额 → 创建 BorrowRecord → 更新双方状态。它不存“借阅列表”,只通过关联关系自然获得
用组合代替继承,用协议代替强耦合
读者分管理员和普通用户?别搞 AdminUser extends User。用组合更干净:User 类有个 role 属性(如枚举 ADMIN/READER),不同角色的操作权限由 Library 根据 role 动态判断。这样加个 STUDENT 角色只需改枚举,不动类结构。
扩展性来自松耦合。比如未来要加微信通知,不要让 BorrowRecord 直接调用微信 SDK。定义一个 Notifier 接口,Library 在创建记录后调用 notifier.send(record) —— 具体是发短信、邮件还是微信,由实现类决定,主流程完全无感。
构造即约束,拒绝非法对象存在
面向对象的边界从对象诞生那一刻就开始守护。Book 构造函数必须校验 ISBN 格式、标题非空;Reader 构造时强制传入有效 readerId 和 name;BorrowRecord 创建时必须带合法的 borrowDate 和 dueDate(比如 dueDate = borrowDate + 30 天,由构造函数算好,不靠外部传入错误值)。
这样系统里永远不会出现“状态为已借出但没关联任何 BorrowRecord”的 Book,也不会有“借了6本书却没报错”的 Reader —— 错误在对象出生时就被拦截,而不是运行中靠 if 判断补救。











