共计 2389 个字符,预计需要花费 6 分钟才能阅读完成。
内容目录
享元模式
概述
享元(Flyweight)模式:运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此又称为轻量级模式。
享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。
我们可以将享元模式与单例模式放在一起谈论,通俗点来讲,单例模式是维护一个对象的重复使用,而享元模式维护的是多个对象的重复使用。
类型
享元模式属于结构性模式。
介绍
- 目的:运用共享技术有效地支持大量细粒度的对象。
- 主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中重复使用的对象抽离出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
- 如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识所标识的对象。
示例代码
假设一个程序需要随机绘制10个圆形,而这些圆形的颜色仅有四种:red、blue、white、black,半径是随机的。
图形操作接口
package flyweight;
public interface IShape {
void draw();
}
圆的实现
package flyweight;
public class Circle implements IShape{
private double radius;
private String color;
public Circle(double radius,String color){
this.radius = radius;
this.color = color;
}
@Override
public void draw() {
System.out.println("绘制了一个半径为:" + radius + ",颜色为:" + color + "的圆.");
}
}
享元类
该类用于管理多个会重复使用的圆实例。
package flyweight;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class FlyweightFactory {
private static final Map<String,IShape> circleMap = new ConcurrentHashMap<String,IShape>();
public static IShape getCircle(String color){
IShape circle = circleMap.get(color);
if ( circle == null){
circle = new Circle(color);
circleMap.put(color,circle);
System.out.println("创建了一个颜色为" + color + "的圆。");
}
return circle;
}
}
测试代码及运行结果如下:
package flyweight;
import org.junit.Test;
/**
* ClassName: FlyweightTest <br/>
*
* @author Ning <br/>
* @date 2023/10/21 0021
* @since JDK 11
*/
public class FlyweightTest {
private static final String colors[] = {"red","blue","white","black"};
@Test
public void flyweightTest(){
for (int i = 0; i < 10; i++) {
Circle circle = (Circle) FlyweightFactory.getCircle(getColor());
circle.setRadius(getRadius());
circle.draw();
}
}
public String getColor(){
return colors[(int) (Math.random() * colors.length)];
}
public double getRadius(){
return Math.random() * 100;
}
}
创建了一个颜色为white的圆。
绘制了一个半径为:66.00547720180391,颜色为:white的圆.
创建了一个颜色为red的圆。
绘制了一个半径为:37.62220674526002,颜色为:red的圆.
绘制了一个半径为:66.55351032418484,颜色为:white的圆.
创建了一个颜色为black的圆。
绘制了一个半径为:34.16085784102466,颜色为:black的圆.
绘制了一个半径为:96.79539622581301,颜色为:white的圆.
绘制了一个半径为:11.015661092424168,颜色为:black的圆.
绘制了一个半径为:99.54145083907062,颜色为:red的圆.
创建了一个颜色为blue的圆。
绘制了一个半径为:70.0762962719384,颜色为:blue的圆.
绘制了一个半径为:73.8598169398206,颜色为:red的圆.
绘制了一个半径为:65.00896272569092,颜色为:white的圆.
享元模式的核心代码就是通过map来存储具有唯一标识和需要重复使用的对象。具体实现可参考上述的FlyweightFactory
.
其它
有个细节值得注意:有些对象本身不一样,但通过一点点变化后就可以复用,我们编程时可能稍不注意就会忘记复用这些对象。比如说伟大的超级玛丽,谁能想到草和云更改一下颜色就可以实现复用呢?还有里面的三种乌龟,换一个颜色、加一个装饰就变成了不同的怪。
在超级玛丽中,这样的细节还有很多,正是这些精湛的复用使得这一款红遍全球的游戏仅有 40KB 大小。正是印证了那句名言:神在细节之中。
正文完