Java案例中的享元模式怎么用?

wen java案例 4

Java享元模式使用案例

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

Java案例中的享元模式怎么用?

场景:图书管理系统

假设我们需要管理一个图书馆的书籍信息,每本书都有书名、作者、出版社等内部状态(可共享),以及位置、借阅者等外部状态(不共享)。

代码实现

// 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)

  • 随环境变化而改变
  • 不能共享
  • 例子中的:位置、借阅者

适用场景

  1. 系统中有大量相似对象
  2. 对象的大部分状态可以外部化
  3. 需要缓冲池的场景

实际应用示例

Java中的String类就使用了享元模式:

// String常量池就是享元模式的实现
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true,共享同一个对象

通过享元模式,我们可以显著减少内存消耗,提高系统性能。

抱歉,评论功能暂时关闭!