博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌
Java知识图谱点击链接:体系化学习Java(Java面试专题)
💕💕 感兴趣的同学可以收藏关注下 ,不然下次找不到哟💕💕
文章目录
- 1、什么是享元模式
- 2、享元模式的优缺点
- 3、享元模式的应用场景
- 4、享元模式的结构
- 5、享元模式的代码案例
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<String, Integer> attackMap = new HashMap<>();
private static Map<String, Integer> 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<String, Monster> 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
💕💕喜欢的话记得点赞收藏啊