【问题标题】:Appropriate datastructure for flyweight享元的适当数据结构
【发布时间】:2020-09-14 09:51:59
【问题描述】:

我正在尝试在生成云的程序中应用享元模式。我有一个代表云的内在状态的类。云类型由其属性定义:

class CloudType {
    float size;
    float altitude;
    String color;
    String texture;

   public void display(x, y) {}

}

class ConcreteCloud {
    float x;
    float y;
    CloudType cloudType;

    void display() {
        cloudeType.display(x, y);
    }
}

我想创建一个 CloudType 工厂,它将这些特征作为参数,如果存在则返回对应的 CloudType 实例,否则先创建并存储它。

class CloudTypeFactory {
    //  SomeContainer<CloudType> container;

    public CloudType getCloudType(float size, float altitude, String color, String texture) {
        CloudType instance = // container get corresponding cloudType
        if (instance == null) {
            instance = new CloudeType(size, altitude, color, texture);
            container.add(instance);
        }
        return instance;
    }

}

问题:

我对使用哪个容器以及架构本身有疑问。可以使用 HashSet,但搜索复杂性与 CloudType 中的属性数量成正比,这似乎不正确。在我在线阅读的示例中,作者使用 HashMap,其键是 CloudType 的名称:这违背了 IMO 的目的,因为在这种情况下可能有无限数量的云类型。

【问题讨论】:

    标签: java search design-patterns data-structures flyweight-pattern


    【解决方案1】:
    1. CloudType 类实现 equals()hashCode(),以便您可以将实例存储在 Map 中。
    2. 使用哈希码作为键。
    3. 实现哈希码算法,以便您可以将sizealtitudecolortexture传递给它。
    4. 使用四个参数生成哈希键以查找CloudType

    类似的东西。

    class CloudType {
        float size;
        float altitude;
        String color;
        String texture;
    
        private static final Map<Integer, CloudType> CACHE = new HashMap<>();
    
        private CloudType(float size, float altitude, String color, String texture) {
            this.size = size;
            this.altitude = altitude;
            this.color = color;
            this.texture = texture;
        }
    
        public static CloudType lookup(float size, float altitude, String color, String texture) {
            int hashKey = hashCode(size, altitude, color, texture);
            return CACHE.computeIfAbsent(hashKey, k -> new CloudType(size, altitude, color, texture));
        }
    
        public void display(float x, float y) {}
    
        //TODO generate equals() method
    
        @Override
        public int hashCode() {
            return hashCode(size, altitude, color, texture);
        }
    
        private static int hashCode(float size, float altitude, String color, String texture) {
            return Objects.hash(size, altitude, color, texture);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您在为享元设计适当的关联存储时遇到的问题可能表明您的情况可能不是享元模式的良好目标。特别是,对象的两个固有状态是浮点值。这是不寻常的。在实践中,这意味着您可以拥有无​​限多的物体,它们的高度或大小差异很小。

      您设计的解决方案应取决于此数据建模的实际需求,以及客户端代码重用CloudTypes 的程度。如果由于浮点精度实际上很重要而重用它们,则享元不合适。相反,如果在实践中只使用有限数量的sizealtitude 值,那么将这些值离散化并使用它们来构造用于关联存储的主键是有意义的。

      【讨论】:

        猜你喜欢
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2013-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-31
        • 2021-09-25
        相关资源
        最近更新 更多