小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
概述
享元模式,是结构型设计模式的一种,主要用于减少创建对象的数量,是池技术的重要实现方式,可以降低大量重复的、细粒度的类在内存中的开销,以减少内存占用和提高性能。
角色
抽象享元:类中包含原始对象中部分能在多个对象中共享的状态,享元中存储的状态被称为“内在状态”,外部通过参数型数传入的称为“外在状态”。
具体享元:实现抽象享元定义的业务,其内部状态必须与环境无关,使其可以在系统内共享。
享元工厂:主要用来构造一个容器池,负责创建和管理享元对象,提供获取享元对象的方法,保证其可以适当的被系统共享。客户端发起请求后,它会先检查池中是否有符合要求的对象,如果有则返回该对象,如果没有就根据参数创建新的享元对象。
客户端:负责计算或存储享元的外在状态,对于客户端来说,享元是一种可以在运行时进行配置的模板对象。
模板
抽象享元:定义了图形所需实现的功能。
/**
* 图形接口
*/
public interface Shape {
/**
* 绘制图形
*/
void draw();
}
具体享元:实现了图形接口的绘制功能,同时定义了若干内在状态与外在状态。
/**
* 圆形
*/
public class Circle implements Shape {
/**
* 颜色
*/
private String color;
/**
* X坐标
*/
private int x;
/**
* Y坐标
*/
private int y;
/**
* 半径
*/
private int radius;
@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color
+ ", x : " + x + ", y :" + y + ", radius :" + 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;
}
}
享元工厂:创建一个工厂,生成基于给定信息的实体类的对象,通过Map模拟容器池存储享元对象。
/**
* 享元工厂
*/
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("---------------------------------------------------------------");
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
客户端:使用工厂类,通过传递颜色信息来获取实体类的对象。
public class FlyweightPatternDemo {
/**
* 颜色数组
*/
private static final String[] colors = {"Red", "Green", "Blue", "White", "Black"};
private static Random random = new Random();
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[random.nextInt(colors.length)];
}
/**
* 随机生成X坐标
*/
private static int getRandomX() {
return random.nextInt(100);
}
/**
* 随机生成Y坐标
*/
private static int getRandomY() {
return random.nextInt(100);
}
}
小结
优点
提高性能:大幅减少内存中对象的数量,降低程序对内存的占用。
缺点
复杂化:提高了系统的复杂度,需要分离出外部状态和内部状态,而且内部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
耗时变长:每次调用都需要读取外部状态,进行重新计算,变相延长程序运行耗时。
适用场景
- 系统中有大量相似的对象,且这些对象耗费大量内存。
- 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关。
- 需要缓冲池的场景。
最后
文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!!!
如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!