Java享元模式使用案例
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,通过共享对象来降低内存消耗,下面通过一个实际案例来说明。

场景:图书管理系统
假设我们需要管理一个图书馆的书籍信息,每本书都有书名、作者、出版社等内部状态(可共享),以及位置、借阅者等外部状态(不共享)。
代码实现
// 1. 享元接口
public interface Book {
void display(String location, String borrower);
}
// 2. 具体享元类 - 书籍信息
public class BookInfo implements Book {
// 内部状态(可共享)
private String title;
private String author;
private String publisher;
public BookInfo(String title, String author, String publisher) {
this.title = title;
this.author = author;
this.publisher = publisher;
System.out.println("创建书籍:" + title);
}
@Override
public void display(String location, String borrower) {
System.out.println("书名:" + title +
" | 作者:" + author +
" | 位置:" + location +
" | 借阅者:" + borrower);
}
}
// 3. 享元工厂
public class BookFactory {
private static Map<String, BookInfo> bookPool = new HashMap<>();
public static BookInfo getBook(String title, String author, String publisher) {
String key = title + "_" + author + "_" + publisher;
BookInfo book = bookPool.get(key);
if (book == null) {
book = new BookInfo(title, author, publisher);
bookPool.put(key, book);
} else {
System.out.println("复用书籍:" + title);
}
return book;
}
public static int getBookCount() {
return bookPool.size();
}
}
// 4. 客户端使用
public class FlyweightDemo {
public static void main(String[] args) {
// 创建不同位置的同一本书
BookInfo book1 = BookFactory.getBook("Java编程思想", "Bruce Eckel", "机械工业出版社");
book1.display("A区1架", "张三");
BookInfo book2 = BookFactory.getBook("Java编程思想", "Bruce Eckel", "机械工业出版社");
book2.display("B区2架", "李四");
BookInfo book3 = BookFactory.getBook("设计模式", "GoF", "电子工业出版社");
book3.display("C区3架", "王五");
// 验证是否是同一个对象
System.out.println("\nbook1 == book2: " + (book1 == book2)); // true
System.out.println("总共创建了 " + BookFactory.getBookCount() + " 本不同的书");
}
}
运行结果
创建书籍:Java编程思想
书名:Java编程思想 | 作者:Bruce Eckel | 位置:A区1架 | 借阅者:张三
复用书籍:Java编程思想
书名:Java编程思想 | 作者:Bruce Eckel | 位置:B区2架 | 借阅者:李四
创建书籍:设计模式
书名:设计模式 | 作者:GoF | 位置:C区3架 | 借阅者:王五
book1 == book2: true
总共创建了 2 本不同的书
类图结构
classDiagram
class Book {
<<interface>>
+display(location: String, borrower: String): void
}
class BookInfo {
-title: String
-author: String
-publisher: String
+display(location: String, borrower: String): void
}
class BookFactory {
-bookPool: Map<String, BookInfo>
+getBook(title, author, publisher): BookInfo
+getBookCount(): int
}
Book <|.. BookInfo
BookFactory --> BookInfo : 创建
关键点说明
内部状态(Intrinsic State):
- 不随环境变化而改变
- 可以共享
- 例子中的:书名、作者、出版社
外部状态(Extrinsic State):
- 随环境变化而改变
- 不能共享
- 例子中的:位置、借阅者
适用场景:
- 系统中有大量相似对象
- 对象的大部分状态可以外部化
- 需要缓冲池的场景
实际应用示例
Java中的String类就使用了享元模式:
// String常量池就是享元模式的实现 String s1 = "hello"; String s2 = "hello"; System.out.println(s1 == s2); // true,共享同一个对象
通过享元模式,我们可以显著减少内存消耗,提高系统性能。