重学设计模式之享元模式

目录

  • 定义
  • 使用场景
  • 代码实现

定义

享元模式使共享对象可有效的支持大量的细粒度的对象。享元模式将共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。享元模式中部分对象是可以共享的,可以共享的状态为内部状态,内部状态不会随着环境变化。不可共享的对象称为外部状态,它不会随着环境改变而改变。

使用场景

  1. 系统中需要生成大量的相似的对象。
  2. 细颗粒度的对象都具有接近的外部状态,而且内部状态与环境无关,也就是对象没有特定身份。
  3. 需要缓冲池的场景。

代码实现

  1. 将需要改写为享元的类成员变量拆分为两个部分:
    • 内在状态:包含不变的、可在许多对象中重复使用的数据的成员变量。
    • 外在状态:包含每个对象各自不同的情景数据的成员变量。
  2. 保留类中表示内在状态的成员变量,并将其属性设置为不可修改。这些变量仅可在构造函数中获得初始数值。
  3. 找到所有使用外在状态成员变量的方法,为在方法中所用的每个成员变量新建一个参数,并使用该参数代替成员变量。
  4. 有选择地创建工厂类来管理享元缓存池,它负责在新建享元时检查已有的享元。如果选择使用工厂,客户端就只能通过工厂来请求享元,它们需要将享元的内在状态作为参数传递给工厂。
  5. 客户端必须存储和计算外在状态(情景)的数值,因为只有这样才能调用享元对象的方法。为了使用方便,外在状态和引用享元的成员变量可以移动到单独的情景类中。
public class Circle {
    private String color;
    private int x;
    private int y;
    private int radius;

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

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

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

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

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

public class ShapeFactory {

    private static final HashMap<String, Circle> circleMap = new HashMap<>();

    public static Circle getCircle(String color) {
        Circle circle = circleMap.get(color);
        if (circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle);
            System.out.println("Creating circle of color : " + color);
        } else {
            System.out.println("Get local circle of color : " + color);
        }
        return circle;
    }
}

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

    @Test
    public void test() {
        for (int i = 0; i < 10; ++i) {
            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);
    }
}

Creating circle of color : White
Circle: Draw() [Color : White, x : 20, y :92, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 11, y :10, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 13, y :8, radius :100
Get local circle of color : Green
Circle: Draw() [Color : Green, x : 54, y :41, radius :100
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 11, y :1, radius :100
Get local circle of color : Blue
Circle: Draw() [Color : Blue, x : 83, y :27, radius :100
Get local circle of color : White
Circle: Draw() [Color : White, x : 82, y :71, radius :100
Get local circle of color : Blue
Circle: Draw() [Color : Blue, x : 68, y :72, radius :100
Get local circle of color : White
Circle: Draw() [Color : White, x : 3, y :52, radius :100
Get local circle of color : Black
Circle: Draw() [Color : Black, x : 28, y :54, radius :100
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享