标签:享元 怪兽 战斗力 皮肤 模式 设计模式 public String
享元模式(Flyweight Pattern) – 设计模式之结构型模式:
目录
享元模式(Flyweight Pattern)
定义: Use sharing to support large numbers of fined-grained objects efficiently.
运用共享技术有效地支持大量细粒度的对象
要求细粒度对象,那么不可避免地使得对象数量多且性质相近,那我们就将这些对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。
1 内部状态
内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改变,如我们例子中的skinColor、battleEffectiveness等,它们可以作为一个对象的动态附加信息,不必直接储存在具体某个对象中,属于可以共享的部分。
2 外部状态
外部状态是对象得以依赖的一个标记,是随环境改变而改变的、不可以共享的状态,如我们例子中的type,它是一批对象的统一标识,是唯一的一个索引值。
类图
享元模式通用类图:
例子-开关:
过程:
在打怪游戏里面有战士,有怪兽,随机生成战士和怪兽
类图:
代码:
抽象享元角色 Flyweight
它简单地说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
public interface GenerateFlyweight {
void generate();
}
抽象享元角色一般为抽象类,在实际项目中,一般是一个实现类,它是描述一类事物的方法。在抽象角色中,一般需要把外部状态和内部状态(当然了,可以没有内部状态,只有行为也是可以的)定义出来,避免子类的随意扩展。
具体享元角色 MonstersFlyweight
具体的一个产品类,实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态,这是绝对不允许的。
public class MonstersFlyweight implements GenerateFlyweight {
private String type; // 类型
private String skinColor; // 皮肤
private int battleEffectiveness; // 战斗力
public MonstersFlyweight(String type) {
this.type = type;
}
public void setSkinColor(String skinColor) {
this.skinColor = skinColor;
}
public void setBattleEffectiveness(int battleEffectiveness) {
this.battleEffectiveness = battleEffectiveness;
}
@Override
public void generate() {
System.out.println("一位拥有"+skinColor+"皮肤,"+"战斗力为:"+battleEffectiveness+"的怪兽");
}
}
具体享元角色 SoldierFlyweight
public class SoldierFlyweight implements GenerateFlyweight {
private String type; // 类型
private String skinColor; // 皮肤
private int battleEffectiveness; // 战斗力
public SoldierFlyweight(String type) {
this.type = type;
}
public void setSkinColor(String skinColor) {
this.skinColor = skinColor;
}
public void setBattleEffectiveness(int battleEffectiveness) {
this.battleEffectiveness = battleEffectiveness;
}
@Override
public void generate() {
System.out.println("一位拥有"+skinColor+"皮肤,"+"战斗力为:"+battleEffectiveness+"的战士");
}
}
具体享元角色实现自己的业务逻辑,然后接收外部状态,以便内部业务逻辑对外部状态的依赖。注意,我们在抽象享元中对外部状态加上了final关键字,防止意外产生,什么意外?
获得了一个外部状态,然后无意修改了一下,池就混乱了!
注意 在程序开发中,确认只需要一次赋值的属性则设置为final类型,避免无意修改导致逻辑混乱,特别是Session级的常量或变量。
工厂类
public class FlyweightFactory {
private static final Map<String, GenerateFlyweight> flyweightMap = new HashMap<>();
public FlyweightFactory() {
}
public static GenerateFlyweight getInstance(String typpe) {
// 缓存里如果没有对应的内容,则实例化并放入缓存。
if (!flyweightMap.containsKey(typpe)) {
switch (typpe) {
case "soldier":
flyweightMap.put(typpe, new SoldierFlyweight(typpe));
break;
case "monsters":
flyweightMap.put(typpe, new MonstersFlyweight(typpe));
break;
}
}
// 缓存里必然有内容,直接取得并返回
return flyweightMap.get(typpe);
}
}
测试:
public class FlyweightTest {
private static final String COLORS[] =
{ "红色", "粉红色", "绿色", "蓝色", "棕色", "橘色" };
public static void main(String[] args) {
System.out.println("========== 怪兽 ============");
for(int i=0; i < 10; ++i) {
MonstersFlyweight flyweight = (MonstersFlyweight) FlyweightFactory.getInstance("monsters");
flyweight.setSkinColor(getRandomColor());
flyweight.setBattleEffectiveness(getRandomBattleEffectiveness());
flyweight.generate();
}
System.out.println("========== 战士 ============");
for(int i=0; i < 10; ++i) {
SoldierFlyweight flyweight = (SoldierFlyweight) FlyweightFactory.getInstance("soldier");
flyweight.setSkinColor(getRandomColor());
flyweight.setBattleEffectiveness(getRandomBattleEffectiveness());
flyweight.generate();
}
}
private static String getRandomColor() {
return COLORS[(int)(Math.random()*COLORS.length)];
}
private static int getRandomBattleEffectiveness() {
return (int)(Math.random()*1000+100);
}
}
结果:
========== 怪兽 ============
一位拥有蓝色皮肤,战斗力为:119的怪兽
一位拥有橘色皮肤,战斗力为:414的怪兽
一位拥有蓝色皮肤,战斗力为:101的怪兽
一位拥有红色皮肤,战斗力为:172的怪兽
一位拥有蓝色皮肤,战斗力为:495的怪兽
一位拥有红色皮肤,战斗力为:1034的怪兽
一位拥有棕色皮肤,战斗力为:284的怪兽
一位拥有红色皮肤,战斗力为:742的怪兽
一位拥有粉红色皮肤,战斗力为:574的怪兽
一位拥有橘色皮肤,战斗力为:816的怪兽
========== 战士 ============
一位拥有棕色皮肤,战斗力为:802的战士
一位拥有棕色皮肤,战斗力为:420的战士
一位拥有绿色皮肤,战斗力为:515的战士
一位拥有蓝色皮肤,战斗力为:295的战士
一位拥有绿色皮肤,战斗力为:189的战士
一位拥有绿色皮肤,战斗力为:753的战士
一位拥有粉红色皮肤,战斗力为:306的战士
一位拥有红色皮肤,战斗力为:917的战士
一位拥有红色皮肤,战斗力为:647的战士
一位拥有棕色皮肤,战斗力为:962的战士
总结:
享元模式,是简单工厂模式和对象创建的结合。我也没看懂这个模式特别的地方。姑且先这样吧,后面有再深入的学习,再补充。
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
使用场景
1,系统中存在大量的相似对象。
2,细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
3,需要缓冲池的场景。
标签:享元,怪兽,战斗力,皮肤,模式,设计模式,public,String
来源: https://blog.csdn.net/qq_35461948/article/details/113954567
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。