代码改变世界

享元模式 Flyweight Pattern

2019-09-06 12:30  tonyniu8  阅读(94)  评论(0)    收藏  举报

本文引用了如下两篇文章。

享元模式

https://www.runoob.com/design-pattern/flyweight-pattern.html

https://blog.csdn.net/qq_29676623/article/details/86092616

运用共享技术,有效支持大量细粒度对象。减少对象的创建。

应用场景:

1.如果一个应用程序要造大量的对象,而大量的对象造成了大量的存储开销, 就应该考虑使用。

2.如果有大量外部状态, 去除外部状态后, 有共同特性, 可以考虑享元。 比如五子棋, 跳棋, object 颜色是内部状态, 位置不同。位置是外部状态。

扩展:

内部状态:指在享元对象的内部并且不会随着环境改变而改变的共享部分.

外部状态:比如棋子的位置。

 

优点:大大减少对象的创建,降低系统的内存,使效率提高。

缺点:提高了系统的复杂度,需要分离出外部状态和内部状态。

 

 

例子

Coding :

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类 Circle。下一步是定义工厂类 ShapeFactory

ShapeFactory 有一个 Circle 的 HashMap,其中键名为 Circle 对象的颜色。无论何时接收到请求,都会创建一个特定颜色的圆。ShapeFactory 检查它的 HashMap 中的 circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 hashmap 中以备后续使用的新对象,并把该对象返回到客户端。

 

public interface Shape {
   void draw();
}

package com.designpattern.flyweight;

public class Circle implements Shape {
    private String color;
    private int x;
    private int y;
    private int radius;

    public Circle(String color) {
        this.color = color;
    }

    @Override
    public void draw() {
         System.out.println("Circle: Draw() [Color : " + color 
                 +", x : " + x +", y :" + y +", radius :" + radius);

    }

    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 int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

}


package com.designpattern.flyweight;

import java.util.HashMap;

public class ShapeFactory {
    private static final HashMap<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        Circle circle = (Circle) circleMap.get(color);

        if (circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle);
            System.out.println("Creating circle of color: " + color);
        }
        return circle;
    }
}
package com.designpattern.flyweight;

public class FlyweightPatternDemo {
    private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());
            circle.setX(getRandomx());
            circle.setY(getRandomy());
            circle.setRadius(100);
             circle.draw();
        }
    }

    private static String getRandomColor() {
        return colors[(int) (Math.random() * colors.length)];
    }

    private static int getRandomx() {
        return (int) (Math.random() * 100);
    }

    private static int getRandomy() {
        return (int) (Math.random() * 100);
    }
    
    private static int get(String value) {
        return Integer.valueOf(value);
    }

} 

 

Java source code 例子,Integer  

 /**
     
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }