享元模式



享元模式


1. 介绍

享元模式(Flyweight Pattern)是一种结构型模式。当需要使用某个对象时,享元模式会先去查找是否存在相同的对象,如果存在,就使用已经存在的对象;如果不存在,才会去创建新的对象;这样就可以减少对象的数量,降低内存消耗和提高性能。

简单理解:享元模式和我们的共享单车很像,如果我们需要使用共享单车,我们不需要去购买一辆新的单车,只需要去找一辆共享单车就可以了。


优点:

  1. 减少对象的数量。如果对象需要消耗恒很多的资源,或者过程很复杂,需要花费较长的时间,使用享元模式无疑会减少对象的创建和对象的数量。

缺点:

  1. 不是适用所有的情况。如果外部状态有固有化的性质,且随着内部状态的变化而变化,就不能使用享元模式。

2. 例子

我们在一个ShapeFactory中使用一个HashMap来存储不同颜色的圆形,键是圆形的颜色,如果需要的某种颜色的圆在map中存在,就直接将map中该种的颜色的圆形对象返回,否则创建一个新的该种颜色的圆形对象,将其返回后加入到map中。


类图:
在这里插入图片描述

Shape接口:
图形接口,圆形(Circle)实现了这个接口。

package flyWeightPattern;

public interface Shape {
    public void draw();
}

Circle类:
代表的是圆形,它实现了Shape接口。

package flyWeightPattern;

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

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

    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public void draw() {
        System.out.println(String.format("半径为%s,圆心为(%s,%s),颜色为%s", radius, x, y, color));
    }

    public Circle(int radius, int x, int y, String color) {
        super();
        this.radius = radius;
        this.x = x;
        this.y = y;
        this.color = color;
    }

    public Circle() {
        super();
    }

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

}

ShapeFactory类:
这个类中使用了一个HashMap来实现享元模式。

package flyWeightPattern;

import java.util.HashMap;
import java.util.Random;

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

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

        if (circle == null) {
            circle = new Circle(color);
            circle.setRadius(getRandomInt());
            circle.setX(getRandomInt());
            circle.setY(getRandomInt());
            circleMap.put(color, circle);
        }
        return circle;
    }

    public static int getRandomInt() {
        Random random = new Random();
        return random.nextInt(100);
    }
}

测试类:

package flyWeightPattern;

import org.junit.Test;

public class TestJ {
    String[] colorList = {"green", "black", "red", "white"};
    @Test
    public void test1() {
        for (int i = 0; i < 10; i++) {
            Circle circle = ShapeFactory.getCircle(getRandomColor());
            System.out.println(circle.toString());
            //从打印的结果可以看出,如果获取在HashMap中存在的颜色的圆,它返回的是在HashMap中以经
            //存在的对象,如果获取的圆的颜色在HashMap中不存在,就会新创建一个对象,并将其加入到HashMap中。
            //这就是享元模式,大大减少新的对象的创建
        }
    }
    
    public String getRandomColor() {
        return colorList[(int) Math.floor(Math.random()*colorList.length)];
    }
    

}

运行结果:

Circle [radius=67, x=43, y=57, color=black]
Circle [radius=21, x=66, y=51, color=white]
Circle [radius=21, x=66, y=51, color=white]
Circle [radius=21, x=66, y=51, color=white]
Circle [radius=67, x=43, y=57, color=black]
Circle [radius=50, x=25, y=16, color=green]
Circle [radius=58, x=59, y=41, color=red]
Circle [radius=21, x=66, y=51, color=white]
Circle [radius=21, x=66, y=51, color=white]
Circle [radius=67, x=43, y=57, color=black]

3. 总结

享元模式和共享单车很相似,当需要一个对象时,享元模式会首先判断是否存在这种对象,如果存在,就使用这个对象,如果不存在,才会创建新的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值