0
点赞
收藏
分享

微信扫一扫

享元设计模式 和 享元设计模式在 FastDateFormat类中的应用


1. 概述

享元设计模式(Flyweight Pattern):通过尽量共享实例来避免new出实例。

享元设计模式中有两个角色,一是要共享的实例,二是获取或创建这些共享实例的工厂。

举一个例子:例如 String 常量池,大家创建的String常量,创建String的时候,先去常量池中看一下,有该String常量直接使用该常量,如果没有就去创建,创建成功后放在常量池中,当然这些常量不允许修改的,享元模式中的共享的实例也不允许修改,一旦被修改,大家在共用的时候就会出现问题。

享元设计模式 和 享元设计模式在 FastDateFormat类中的应用_apache

2. 享元设计模式在 FastDateFormat类中的应用

这里的FastDateFormat指的是 apache 工具包(org.apache.commons.lang3.time)里面的一个类。

FastDateFormat 类既充当工厂角色,也充当共享的对象,pool是一个Map,key 是 getInstance 方法的参数,value 是 FastDateFormat实例,参数是日期的格式,例:yyyy-MM-dd。

享元设计模式 和 享元设计模式在 FastDateFormat类中的应用_设计模式_02


先看下 getInstance 方法,该方法第一步使用参数生成 key,使用 key 去获取 共享的 FastDateFormat 对象,无已经创建的 FastDateFormat 共享对象则创建。

public F getInstance(final String pattern, TimeZone timeZone, Locale locale) {
        Validate.notNull(pattern, "pattern must not be null");
        if (timeZone == null) {
            timeZone = TimeZone.getDefault();
        }
        if (locale == null) {
            locale = Locale.getDefault();
        }
        // 使用参数生成 key
        final MultipartKey key = new MultipartKey(pattern, timeZone, locale);
        // 使用 key 去获取 共享的 FastDateFormat 对象
        F format = cInstanceCache.get(key);
        // 无已经创建的 FastDateFormat 共享对象则创建
        if (format == null) {
            format = createInstance(pattern, timeZone, locale);
            final F previousValue= cInstanceCache.putIfAbsent(key, format);
            if (previousValue != null) {
                // another thread snuck in and did the same work
                // we should return the instance that is in ConcurrentMap
                format= previousValue;
            }
        }
        return format;
    }

pool 如下所示

private final ConcurrentMap<MultipartKey, F> cInstanceCache = new ConcurrentHashMap<>(7);

key 如下所示, key 是使用 getInstance 方法参数通过计算(下面代码中的hashCode方法)得来:

private static class MultipartKey {
        private final Object[] keys;
        private int hashCode;

        /**
         * Constructs an instance of <code>MultipartKey</code> to hold the specified objects.
         * @param keys the set of objects that make up the key.  Each key may be null.
         */
        MultipartKey(final Object... keys) {
            this.keys = keys;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean equals(final Object obj) {
            // Eliminate the usual boilerplate because
            // this inner static class is only used in a generic ConcurrentHashMap
            // which will not compare against other Object types
            return Arrays.equals(keys, ((MultipartKey)obj).keys);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode() {
            if(hashCode==0) {
                int rc= 0;
                for(final Object key : keys) {
                    if(key!=null) {
                        rc= rc*7 + key.hashCode();
                    }
                }
                hashCode= rc;
            }
            return hashCode;
        }
    }

参考文献

  • 图解设计模式 结成浩
  • 图解设计模式 尚硅谷


举报

相关推荐

0 条评论