享元模式【结构模式】

享元模式

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;
    }
}

posted on 2018-12-23 14:26  竺旭东  阅读(94)  评论(0编辑  收藏  举报

导航