1、享元模式的学习
当我们需要创建大量相似的对象时,享元模式(Flyweight Pattern)可以提供一种有效的解决方案。享元模式旨在通过共享对象来最小化内存使用和提高性能。它将对象分为可共享的内部状态(Intrinsic State)和不可共享的外部状态(Extrinsic State),并通过共享内部状态来减少对象的数量。
在享元模式中,共享对象由享元工厂(Flyweight Factory)来管理。当客户端需要一个对象时,它可以向享元工厂请求一个实例。如果工厂已经创建了一个相同的对象实例,则返回该实例;否则,工厂将创建一个新的对象实例并将其加入到内部存储中。
以下是享元模式的几个关键角色:
- 享元接口(Flyweight):定义共享对象的接口,包括操作内部状态的方法。
- 具体享元类(Concrete Flyweight):实现享元接口,存储内部状态,并对内部状态进行操作。
- 享元工厂类(Flyweight Factory):负责管理和提供享元对象。它维护一个享元池(Flyweight Pool)来存储已创建的享元对象。
2、享元模式的使用
假设你正在开发一个游戏,其中有多个怪物对象,每个怪物对象都有自己的类型和位置信息。怪物的类型包括"小怪物"、“中怪物"和"大怪物”。
享元接口
public abstract class AbstractMonster {
/**
* 获取类型
*
* @return
*/
protected abstract String getType();
/**
* 获取位置
*
* @param position
* @return
*/
protected abstract String getPosition(String position);
protected String getMonster(String position) {
return getType() + getPosition(position);
}
}
具体享元类(小怪物)
public class SmallMonster extends AbstractMonster {
@Override
protected String getType() {
System.out.println("type是small的怪物");
return "type是small的怪物";
}
@Override
protected String getPosition(String position) {
System.out.println("position信息是:" + position);
return "position信息是:" + position;
}
}
具体享元类(中怪物)
public class MiddleMonster extends AbstractMonster {
@Override
protected String getType() {
System.out.println("type是middle的怪物");
return "type是middle的怪物";
}
@Override
protected String getPosition(String position) {
System.out.println("position信息是:" + position);
return "position信息是:" + position;
}
}
具体享元类(大怪物)
public class BigMonster extends AbstractMonster {
@Override
protected String getType() {
System.out.println("type是big的大怪物");
return "type是big的大怪物";
}
@Override
protected String getPosition(String position) {
System.out.println("position信息:" + position);
return "position信息:" + position;
}
}
享元工厂
public class MonsterFactory {
private Map<MonsterTypeEnum, AbstractMonster> monsterMap = new HashMap<>();
private static MonsterFactory monsterFactory = null;
private MonsterFactory() {
}
public synchronized static MonsterFactory getInstance() {
if (Objects.isNull(monsterFactory)) {
monsterFactory = new MonsterFactory();
}
return monsterFactory;
}
public String getMonster(MonsterTypeEnum type, String position) {
AbstractMonster abstractMonster = monsterMap.get(type);
if (Objects.isNull(abstractMonster)) {
switch (type) {
case SMALL:
monsterMap.put(MonsterTypeEnum.SMALL, new SmallMonster());
case MIDDLE:
monsterMap.put(MonsterTypeEnum.MIDDLE, new MiddleMonster());
case BIG:
monsterMap.put(MonsterTypeEnum.BIG, new BigMonster());
}
abstractMonster = monsterMap.get(type);
}
return abstractMonster.getMonster(position);
}
}
怪物类型状态枚举
public enum MonsterTypeEnum {
SMALL("small"), MIDDLE("middle"), BIG("big");
private String name;
MonsterTypeEnum(String name) {
this.name = name;
}
}
客户端
public class MonsterClient {
public static void main(String[] args) {
MonsterFactory.getInstance().getMonster(MonsterTypeEnum.MIDDLE,"东北");
MonsterFactory.getInstance().getMonster(MonsterTypeEnum.BIG,"西北");
MonsterFactory.getInstance().getMonster(MonsterTypeEnum.SMALL,"西南");
}
}
type是middle的怪物
position信息是:东北
type是big的大怪物
position信息:西北
type是small的怪物
position信息是:西南
3、总结
享元模式的核心思想是将对象的状态分为内部状态和外部状态,并共享内部状态以减少对象的数量。这样可以节省内存空间,并提高系统的性能。