享元模式
Use sharing to support large numbers of fine-grained objects efficiently.
使用共享来支持大量细粒度对象
public class FlyWeight {
/**
* 享元模式:
* Use sharing to support large numbers of fine-grained objects efficiently.
* 使用共享来支持大量细粒度对象
*/
@Test
public void all() {
final String[] cities = { "杭州", "上海", "北京", "苏州" };
final String[] depts = { "人事部", "研发部", "财务部", "产品部" };
final ThreadLocalRandom current = ThreadLocalRandom.current();
IntStream.rangeClosed(0, 29).forEach(order -> {
final String city = cities[current.nextInt(cities.length)];
final String dept = depts[current.nextInt(depts.length)];
final Employe employe = Employe.builder().name("zxd" + order).location(LocaltionPool.get(city, dept)).build();
employe.show();
});
}
}
/**
* 1)提取出不可变部分,该部分可实现共享。
*/
@Data
@Builder
class Location {
private final String city;
private final String dept;
}
/**
* 2)包含可变部分和不可变部分的实例对象
*/
@Data
@Builder
@Slf4j
class Employe {
private String name;
private Location location;
public void show() {
log.info("{} {} {} {}", name, "入职了", location.getCity(), location.getDept());
}
}
/**
* 3)基于不可变部分构建共享池
*/
@Slf4j
class LocaltionPool {
private static final String KEY_SEP = "-";
/**
* 内置的城市和部门
*/
private static final String[] CITIES = { "杭州", "上海", "北京" };
private static final String[] DEPTS = { "人事部", "研发部", "财务部", "产品部" };
/**
* 基于 ConcurrentHashMap 构建的内存缓存池
*/
private static final ConcurrentMap<String, Location> locations;
static {
/**
* 初始化内置的城市和部门
*/
locations = new ConcurrentHashMap<>();
Arrays.stream(CITIES).forEach(city -> {
Arrays.stream(DEPTS).forEach(dept -> {
locations.put(new StringJoiner(KEY_SEP).add(city).add(dept).toString(), Location.builder().city(city).dept(dept).build());
});
});
}
public static final Location get(String city, String dept) {
final String key = String.join(KEY_SEP, city, dept);
final Location location = locations.get(key);
if (null != location) {
log.info("从缓存池中获取");
return location;
}
final Location build = Location.builder().city(city).dept(dept).build();
locations.put(key, build);
log.info("对象加入缓存池", build);
return build;
}
}