一 引入
在图书中我们有多个书籍,书籍包含了作者以及书名等信息,但是图书馆的书并不是白来的,当然是自己去购买的。如果学生想看的书没有那么就需要去购买,也就是创建Book对象,但是如果存在了那么就不需要去购买,而是直接使用.这里就引入了享元模式
二 享元模式结构图
- FlyWeight 是抽象的享元角色,他是产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现
- ConcretelyWeight 是具体的享元角色,是具体的产品类,实现抽象角色定义相关业务
- UnsharedconcreteFlyWeight 是不可共享的角色,一般不会出现在享元工厂
- FlyWeightfactory 享元工厂类,用于构建一个池容器(集合),同时提供从池中获取对象方法
三 代码实现
共享实例
@Data
@ToString
public class Book {
String name;
String author;
protected Book(String name, String author) {
this.name = name;
this.author=author;
}
}
共享工厂
public class BookFactory {
Map<String, Book> books = new ConcurrentHashMap<String, Book>();
// 通过懒汉模式创建工厂
private static BookFactory instance = new BookFactory();
private BookFactory(){
}
public static BookFactory getInstance(){
return instance;
}
Book createBook(String name,String author){
Book book = books.get(name);
if (book != null){
return book;
}else {
book = new Book(name, author);
books.put(name,book);
return book;
}
}
}
客户端调用
public class Client {
public static void main(String[] args) {
BookFactory bookFactory = BookFactory.getInstance();
Book book = bookFactory.createBook("java设计模式", "test");
Book book2 = bookFactory.createBook("java设计模式", "test");
System.out.println(book == book2);
}
}
调用结果:
true
说明返回的为同意对象
四 源码中享元模式的应用
Integer.valueOf
初始化缓存
在源码String常量池、数据库连接池也使用了该模式
五 总结
优点:
- 大大减少了对象的创建,降低了程序内存的占用,提高效率
缺点: - 高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改
变而改变