oopdesign-patternsflyweight-pattern

Having issue with flyweight pattern


We use flyweight when there is need to crate bulk of a particular kind of object. Because they share a common data (intrinsic state) so helps in reducing memory consumption, and also have their own state (extrinsic state) which is not shared among all the other object. Here is a sample code

public abstract class Shape {

    private String color;
    private int x;
    private int y;

    public Shape(String color) {
        super();
        this.color = color;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public abstract String draw();

    @Override
    public String toString() {
        return "[color=" + color + ", x=" + x + ", y=" + y + "]";
    }


}


public class Circle extends Shape {

    public Circle(String color) {
        super(color);
    }

    @Override
    public String draw() {
        // TODO Auto-generated method stub
        return "Circle " + toString();
    }

}

import java.util.HashMap;

public class ShapeFactory {

    private static HashMap<String, Shape> circle_map = new HashMap<>();

    public static Shape getCircle(String size){
        if(!circle_map.containsKey(size))
            circle_map.put(size, new Circle(size));

        return circle_map.get(size);
    }

}

and the driver

public class ShapeDriver {

    public static void main(String[] args) {

        Shape first_circle = ShapeFactory.getCircle("small");
        first_circle.setX(45);
        first_circle.setY(12);
        Shape second_circle = ShapeFactory.getCircle("small");

        System.out.println("First circle" + first_circle);
        System.out.println("Second circle" + second_circle);

        second_circle.setX(62);
        second_circle.setY(23);

        System.out.println("First circle" + first_circle);
        System.out.println("Second circle" + second_circle);
    }

}

In this example i want size to be intrinsic and coordinates(x, y) to be extrinsic but when ever i change the coordinates of first_circle it also reflect the change in second_circle because they are sharing a complete object not just a single state. The output is as follow

First circle[color=small, x=45, y=12]
Second circle[color=small, x=45, y=12]
First circle[color=small, x=62, y=23]
Second circle[color=small, x=62, y=23]

its equivalent to create an object and store it in different objects, but they all have the same state or data then how they have their own data(extrinsic state)?


Solution

  • Flyweight objects should be immutable.

    In you example, you could desperate the reused part (color/size, your examples conflict) in a separate class and use that as a flyweight.

    Then you would instantiate a new Circle for each location, but reuse the color object.

    public class Color {
         String color;
         public (String color) {
             this.color = color;
         }
         ...
    }    
    
    public abstract class Shape {
    
            private Color color;
            private int x;
            private int y;
    
            public Shape(Color color) {
                super();
                this.color = color;
            }
            ...    
        }
    
    
        public class Circle extends Shape {
    
            public Circle(Color color) {
                super(Color);
            }
    
             ...    
        }
    
    
        public class ShapeFactory {
    
            private static HashMap<String, Color> color_map = new HashMap<>();
    
            public static Shape getCircle(String color){
                if(!color_map.containsKey(color))
                    color_map .put(color, new Color(color));
    
                return new Circle(color_map.get(size));
            }
    
        }