享元模式的学习与使用

25 篇文章 0 订阅
20 篇文章 0 订阅

1、享元模式的学习

  当我们需要创建大量相似的对象时,享元模式(Flyweight Pattern)可以提供一种有效的解决方案。享元模式旨在通过共享对象来最小化内存使用和提高性能。它将对象分为可共享的内部状态(Intrinsic State)和不可共享的外部状态(Extrinsic State),并通过共享内部状态来减少对象的数量。
  在享元模式中,共享对象由享元工厂(Flyweight Factory)来管理。当客户端需要一个对象时,它可以向享元工厂请求一个实例。如果工厂已经创建了一个相同的对象实例,则返回该实例;否则,工厂将创建一个新的对象实例并将其加入到内部存储中。
  以下是享元模式的几个关键角色:

  1. 享元接口(Flyweight):定义共享对象的接口,包括操作内部状态的方法。
  2. 具体享元类(Concrete Flyweight):实现享元接口,存储内部状态,并对内部状态进行操作。
  3. 享元工厂类(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、总结

  享元模式的核心思想是将对象的状态分为内部状态和外部状态,并共享内部状态以减少对象的数量。这样可以节省内存空间,并提高系统的性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值