10.享元模式
一、认识享元模式
1、概念
如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用都创建新的对象。目的是提高系统性能。上面的概念乍一听好像单例模式其实不是,单例模式只保存一个对象,但是这里可以有很多个不同对象,但是每个对象只有一个实例而已。也就是说享元模式使用了单例模式。
角色:
(1)享元工厂(Llibrary):用于创建具体享元类,维护相同的享元对象。当请求对象已经存在时,直接返回对象,不存在时,在创建对象。在例子中的解释就是图书馆,保存了所有的书,当学生借书时,有就拿走,没有买一本新书。这里面其实是使用了单例模式的。
(2)抽象享元(Book):定义需要共享的对象业务接口。享元类被创建出来总是为了实现某些特定的业务逻辑.
(3)具体享元(ConcreteBook):实现抽象享元类的接口,完成某一具体逻辑。在这里表示可以被借出。
在这里享元工厂是享元模式的核心,它需要确保系统可以共享相同的对象。它会维护一个对象列表,当我们想要获取享元类时,如果请求的享元类已经被创建,则直接返回已有的享元类:若没有,则创建一个新的享元对象,并将它加入到维护队列中。
UML类图:
第一步:定义抽象享元类(BookDAO)
public interface BookDAO {
void borrow();
}
具体享元类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ConcreteBook implements BookDAO {
private String name;
@Override
public void borrow() {
System.out.println("图书馆借出一本书,书名是:"+this.name);
}
}
享元工厂
public class Library {
private Map<String,BookDAO> books = new HashMap<>();
private static Library library = new Library();
public static Library getInstance(){
return library;
}
public BookDAO libToBorrow(String bookName){
BookDAO order;
if (books.containsKey(bookName)){
order = books.get(bookName);
}else{
order = new ConcreteBook(bookName);
books.put(bookName,order);
}
return order;
}
public int getAllBook(){
return books.size();
}
}
测试类
public class FlyWeightTest {
private static List<BookDAO> books = new ArrayList<>();
private static Library library;
public static void main(String[] args) {
library = Library.getInstance();
studentBorrow("java编程思想");
studentBorrow("java设计模式");
studentBorrow("java从入门到精通");
System.out.println("前两本没学会,又借了一次");
studentBorrow("java设计模式");
studentBorrow("java编程思想");
for (BookDAO book : books) {
book.borrow();
}
System.out.println("学生一共借了"+books.size()+"本书");
System.out.println("图书馆实际借出"+library.getAllBook()+"本书");
}
private static void studentBorrow(String bookName){
books.add(library.libToBorrow(bookName));
}
}
生活中的例子:
房屋中介
只要是城市,就少不了房屋中介,房屋中介存有大量的出租房屋信息,并且一家房屋中介往往会有很多个门店,但是所有门店都是共享这些房屋信息(共享的是出租房屋的信息)
个人身份证信息
每个中国公民都有一张身份证,并且这张身份证信息在公安系统中是共享的,全国各公安局派出所都会共享你的身份证信息(共享的是个人身份信息)。
高考志愿填报
每所大学在每个省都有明确的招收名额,这些名额对于该省的所有高考生而言都是共享的(共享的是招收名额)。
图书馆
图书馆里的可借书籍,对多有读者是共享的,大家都可以查询此书是否已经被借出去,还剩哪些可借(共享的是图书)。
总结
享元模式,单从概念来讲估计很多人不是很理解,但是从Integer、String已经生活中的场景结合起来理解,就能轻松理解享元模式,享元模式的实现基本上都伴随着一个集合用来存这些对象。
一句话总结:
优化资源配置,减少资源浪费