关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

深入浅出设计模式 - 享元模式

发布时间:2023-06-27 22:00:18
博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家 Java知识图谱点击链接:体系化学习Java(Java面试专题) 感兴趣的同学可以收藏关注下 ,不然下次找不到哟 1、什么是享元模式 享元模式是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。在享元模式中,如果多个对象需要共享相同的状态或数据,那么可以将这些状态或数据抽象出来,作为一个享元对象,由多个对象共享使用。这样可以减少对象的数量,节省内存空间,并且提高系统的性能。 享元模式中的关键是将对象的状态分为内部状态和外部状态。内部状态是可以被多个对象共享的状态,它通常是不变的,而外部状态是不可以被共享的状态,它会随着对象的不同而不同。 在实现享元模式时,通常会使用工厂类来创建享元对象,并且将已经创建的对象保存在一个池中,以便下次使用时直接从池中获取,避免重复创建对象。 享元模式可以用于需要大量相似对象的场景,例如图形编辑器中的图形对象,游戏中的角色对象等。 2、享元模式的优缺点 享元模式的优点: 减少内存消耗:通过共享对象,可以减少系统中对象的数量,从而减少内存消耗。 提高性能:由于共享对象可以避免重复创建对象,因此可以提高系统的性能。 可以实现对象的复用:通过共享对象,可以实现对象的复用,避免重复创建对象。 可以实现对象的可共享性:通过将对象的状态分为内部状态和外部状态,可以实现对象的可共享性。 享元模式的缺点: 实现较为复杂:由于享元模式需要将对象的状态分为内部状态和外部状态,并且需要使用工厂类来管理共享对象,因此实现较为复杂。 可能会影响系统的维护性:由于享元模式将对象的状态分为内部状态和外部状态,因此可能会影响系统的维护性,增加系统的复杂度。 可能会降低代码的可读性:由于享元模式需要使用工厂类来管理共享对象,因此可能会降低代码的可读性。 3、享元模式的应用场景 享元模式的应用场景: 系统中存在大量相似对象,需要缓存这些对象以提高系统性能。 对象的创建和销毁需要消耗大量的资源,需要复用对象以减少资源消耗。 对象的状态可以分为内部状态和外部状态,其中内部状态可以共享,外部状态可以变化。 系统需要提供大量的小粒度对象,需要避免创建过多的对象,以减少内存消耗。 系统需要支持大量的细粒度对象,需要将对象的状态分为内部状态和外部状态,以实现对象的复用和共享。 4、享元模式的结构 享元模式的结构包括以下几个角色: 抽象享元角色(Flyweight):定义享元对象的接口,同时可以接收外部状态作为参数。 具体享元角色(ConcreteFlyweight):实现抽象享元角色的接口,同时维护内部状态。 享元工厂角色(FlyweightFactory):负责创建和管理享元对象,维护享元池。 客户端角色(Client):使用享元对象的客户端,通过享元工厂角色获取享元对象,并传递外部状态。 5、享元模式的代码案例 我们举一个游戏的例子来说明享元模式: package com.pany.camp.design.principle.flyweigh; /** * * @description: 抽象享元类 * @copyright: @Copyright (c) 2022 * @company: Aiocloud * @author: pany * @version: 1.0.0 * @createTime: 2023-06-27 21:19 */ public interface Monster { void attack(); } package com.pany.camp.design.principle.flyweigh; import java.util.HashMap; import java.util.Map; /** * @description: 常量类 * @copyright: @Copyright (c) 2022 * @company: Aiocloud * @author: pany * @version: 1.0.0 * @createTime: 2023-06-27 21:21 */ public class Constants { private static Map attackMap = new HashMap<>(); private static Map defenseMap = new HashMap<>(); static { attackMap.put("dragon", 100); attackMap.put("goblin", 50); attackMap.put("troll", 80); defenseMap.put("dragon", 80); defenseMap.put("goblin", 20); defenseMap.put("troll", 50); } public static int getAttack(String type) { return attackMap.get(type); } public static int getDefense(String type) { return defenseMap.get(type); } } package com.pany.camp.design.principle.flyweigh; /** * * @description: 具体享元类 * @copyright: @Copyright (c) 2022 * @company: Aiocloud * @author: pany * @version: 1.0.0 * @createTime: 2023-06-27 21:20 */ public class ConcreteMonster implements Monster { private String type; // 内部状态 public ConcreteMonster(String type) { this.type = type; } @Override public void attack() { System.out.println("攻击力:" + Constants.getAttack(type) + ",防御力:" + Constants.getDefense(type)); } } package com.pany.camp.design.principle.flyweigh; import java.util.HashMap; import java.util.Map; /** * @description: 享元工厂类 * @copyright: @Copyright (c) 2022 * @company: Aiocloud * @author: pany * @version: 1.0.0 * @createTime: 2023-06-27 21:22 */ public class MonsterFactory { private static Map monsterMap = new HashMap<>(); public static Monster getMonster(String type) { Monster monster = monsterMap.get(type); if (monster == null) { monster = new ConcreteMonster(type); monsterMap.put(type, monster); } return monster; } } package com.pany.camp.design.principle.flyweigh; /** * @description: 客户端类 * @copyright: @Copyright (c) 2022 * @company: Aiocloud * @author: pany * @version: 1.0.0 * @createTime: 2023-06-27 21:22 */ public class Client { public static void main(String[] args) { Monster dragon = MonsterFactory.getMonster("dragon"); dragon.attack(); Monster goblin = MonsterFactory.getMonster("goblin"); goblin.attack(); Monster troll = MonsterFactory.getMonster("troll"); troll.attack(); Monster dragon2 = MonsterFactory.getMonster("dragon"); dragon2.attack(); } } 抽象享元类为 Monster ,具体享元类为 ConcreteMonster ,享元工厂类为 MonsterFactory ,常量类为 Constants ,客户端为 Client 。当需要创建怪物时,可以通过 MonsterFactory 来获取已经创建好的怪物对象,如果对象不存在则创建新的对象并放入享元池中。这样可以避免重复创建相同的对象,提高性能。 输出如下: 攻击力:100,防御力:80 攻击力:50,防御力:20 攻击力:80,防御力:50 攻击力:100,防御力:80 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421喜欢的话记得点赞收藏啊

/template/Home/leiyu/PC/Static