享元模式
定义:运行共享技术有效地支持大量细粒度对象的复用。
享元模式角色介绍
- Flyweight :抽象享元角色,定义公共接口。
- ConcreteFlyweight:具体享元角色,实现Flyweight接口。
- FlyweightFactory:享元工厂,内部持有Flyweight集合实例,负责创建和管理Flyweight实例。
从UML图上看这模式非常好理解很容易掌握。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。这里以借书为例,如果有这本书就从书库里拿,没有就新买一本。
代码示例
图书享元类
public interface Book {
void read();
}
具体图书(童话书)
public class FairyBook implements Book {
private String bookName;
public FairyBook(String bookName) {
this.bookName = bookName;
}
public void read() {
System.out.println(bookName + hashCode());//用hashCode区分实例
}
}
图书享元工厂
public class BookFactory {
private Map<String, Book> bookMap = new HashMap<String, Book>();
public FairyBook getFairyBook(String bookName) {
Book book = null;
//根据书名来找书,如果有就直接取,没有就新建
if (bookMap.containsKey(bookName)) {
book = bookMap.get(bookName);
} else {
book = new FairyBook(bookName);
bookMap.put(bookName, book);
}
return (FairyBook) book;
}
}
客户端
BookFactory bookFactory = new BookFactory();
FairyBook fairyBook1 = bookFactory.getFairyBook("格林童话");
fairyBook1.read();
FairyBook fairyBook2 = bookFactory.getFairyBook("小王子");
fairyBook2.read();
FairyBook fairyBook3 = bookFactory.getFairyBook("格林童话");
fairyBook3.read();
输出为
格林童话1704856573
小王子705927765
格林童话1704856573//与第一本是同个实例
从上面的例子可以看出,再次借阅格林童话是第一次创建的那本,这就是享元模式的作用。享元模式可以节约大量的资源消耗,避免重复创建同一个不同属性的对象,要注意的是跟单例模式不一样,单例模式是创建型模式,只创建唯一属性相同的对象,而享元模式是结构型模式,它根据属性的不同把对象存储起来,保证对象池里的对象都是一个类型但属性不同。不足之处望指教。