giulian5
giulian5

Reputation: 11

Appropriate datastructure for flyweight

I am trying to apply the flyweight pattern in a program that generates clouds. I have a class that represents intrinsic states of clouds. A cloud type is defined by its attributes :

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

I would like to create a CloudType factory that takes these characteristics as arguments and returns the corresponding instance of CloudType if it exists, else create and store it beforehand.

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

}

The problem:

I have doubts concerning which container to use and consequently the architecture itself. A HashSet could be used, but the search complexity gets proportional to the number of attributes in CloudType , which doesn't seem right. In examples I read online, authors use a HashMap with the key being the name of the CloudType: this defeats the purpose IMO as there might be an infinite number of cloud types in this case.

Upvotes: 1

Views: 61

Answers (1)

jaco0646
jaco0646

Reputation: 17144

  1. Implement equals() and hashCode() for the CloudType class, so that you can store instances in a Map.
  2. Use the hash code as the key.
  3. Implement the hash code algorithm so that you can pass size, altitude, color, and texture to it.
  4. Use the four arguments to generate a hash key to look up a CloudType.

Something like this.

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

Upvotes: 0

Related Questions