享元模式(Flyweight Pattern),通过共享的方式高效的支持大量细粒度的对象。主要通过对象的复用来减少对象创建的次数和数量,以减少系统内存的使用和降低系统的负载。享元模式属于结构型模式,在系统需要一个对象时享元模式首先在系统中查找并尝试重用现有的对象,如果未找到匹配的对象,则创建新对象并将其缓存在系统中以便下次使用。
享元模式主要用于避免在有大量对象时频繁创建和销毁对象造成系统资源的浪费,把其中共同的部分抽象出来,如果有相同的业务请求,则直接返回内存中已有的对象,避免重新创建。
创建一个内存管理的工厂,用户通过工厂获取内存,如果在系统内存池有可用内存时直接获取,如果没有则创建一个内存对象并放入内存池,等下次有相同的内存请求时将该内存分配给用户即可。UML设计图如下:
1)Memory内存类:
package cn.jaa.flyweight_pattern;
import lombok.Data;
/**
* @Author: Jaa
* @Description: 内存类
* @Date 2023/12/2
*/
@Data
public class Memory {
// 内存地址id
private String id;
// 内存大小
private int size;
// 是否被占用
private boolean isUsed;
public Memory(String id, int size, boolean isUsed) {
this.id = id;
this.size = size;
this.isUsed = isUsed;
}
}
2)MemoryFactory内存管理工厂类:
package cn.jaa.flyweight_pattern;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* @Author: Jaa
* @Description: 内存管理类
* @Date 2023/12/2
*/
@Slf4j
public class MemoryFactory {
private static List<Memory> memoryList = new ArrayList<>();
/**
* 获取内存
*
* @param size 内存大小
* @return
*/
public static Memory getMemory(int size) {
Memory memory = null;
// 遍历 memoryList 查找与欲获取内存大小相同且未被占用的内存
for (int i = 0; i < memoryList.size(); i++) {
memory = memoryList.get(i);
if (Objects.equals(memory.getSize(), size) && memory.isUsed() == false) {
memory.setUsed(true);
memoryList.set(i, memory);
log.info("get memory from memoryList: " + JSON.toJSONString(memory));
break;
}
}
// 如果内存列表中没有与欲获取大小相等且未被占用的内存,则开辟内存并加入到memoryList中去
if (Objects.isNull(memory)) {
memory = new Memory(UUID.randomUUID().toString(), 64, false);
log.info("apply a new memory by system and add to memoryList: " + memory);
memoryList.add(memory);
}
return memory;
}
/**
* 释放内存
*
* @param id 内存id
*/
public static void releaseMemory(String id) {
for (int i = 0; i < memoryList.size(); i++) {
Memory memory = memoryList.get(i);
if (Objects.equals(id, memory.getId())) {
memory.setUsed(false);
memoryList.set(i, memory);
log.info("release memory into memoryList: " + id);
break;
}
}
}
}
3)测试享元模式:
package cn.jaa.flyweight_pattern;
/**
* @Author: Jaa
* @Description: 测试享元模式
* @Date 2023/12/2
*/
public class FlyweightDemoTest {
public static void main(String[] args) {
Memory memory = MemoryFactory.getMemory(64);
MemoryFactory.releaseMemory(memory.getId());
MemoryFactory.getMemory(64);
}
}
打印结果: