享元模式:运用共享技术有效的支持大量细粒度的对象
主要角色:
抽象享元类:它是产品的抽象类,同时定义出对象的外部状态和内部状态的接口和实现;
具体享元类:是具体享元角色,是具体的产品类,实现抽象角色定义的业务;
享元工厂:它用于构造一个池容器,同时提供从池中获得对象的方法
1、优点
大大减少了对象的创建,降低了程序内存的占用,提高效率
2、缺点
提高了系统的复杂度,需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变。
测试示例:
抽象享元类:
public abstract class Book {
protected String name;
public Book(String name) {
this.name = name;
}
protected abstract void operation();
}
具体享元类:
public class ConcreteBook extends Book{
public ConcreteBook(String name) {
super(name);
}
@Override
protected void operation() {
System.out.println("借了"+this.name);
}
}
享元工厂:
public enum LibraryFactory {
SINGLEON;
private final static Map<String, SoftReference<Book>> bookmap = new ConcurrentHashMap<>();
public static Book getBook(String bookname) {
if (bookmap.containsKey(bookname)) {
return bookmap.get(bookname).get();
} else {
ConcreteBook value = new ConcreteBook(bookname);
bookmap.put(bookname, new SoftReference<>(value));
return value;
}
}
}
测试:
public class Test {
private static String[] dirs={"辟邪剑谱","如来神掌","龟派气功"};
public static void main(String[] args) {
for (int i = 0; i <100000 ; i++) {
String bookname=dirs[new Random().nextInt(dirs.length)];
LibraryFactory.getBook(bookname).operation();
}
}
}
结果:
扩展(包装类使用到了缓存设计(享元模式)):
- Byte (缓存范围:[-128,127])
- Short (缓存范围:[-128,127])
- Long (缓存范围:[-128,127])
- Integer (缓存范围:[-128,127])
- Character (缓存范围:[0,127])
- Boolean (全部缓存)
- Float (没有缓存)
- Doulbe (没有缓存)