享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。所以其核心就是控制类中要有一个HashMap存储已经创建的对象。

以农药中的英雄为例吧:

定义英雄的通用行为

package com.zndroid.dm.FlyweightModel;/*** Created by luzhenyu on 2017/9/6.*//**定义英雄通用的行为*/
public interface IHeroCommon {//英雄行为:释放技能以及物理攻击String releaseKills(int killIndex);String commonAttack();
}

抽象出英雄通用操作

package com.zndroid.dm.FlyweightModel;/*** Created by luzhenyu on 2017/9/6.*//**抽象英雄基类,并规则化可共享以及不可共享的部分*/
public abstract class BaseHero implements IHeroCommon {protected String name;//英雄名字protected String[] kills;public BaseHero() {kills = initKills();name = getName();checkKills();}private void checkKills() {if (kills.length <= 0 && kills.length > 3)return;//王者荣耀最多三个技能吧}//每个英雄技能以及名字不共享public abstract String[] initKills();public abstract String getName();public abstract String passiveKill();//被动技能//但是释放技能是共享,每个英雄大同小异@Overridepublic String releaseKills(int killIndex) {return  name + " release " + kills[killIndex] + " + 被动 " + passiveKill() + " biu biu biu ~ ";}@Overridepublic String commonAttack() {return name + " release 物理攻击 kua kua kua ~";}
}

下面是具体的英雄实现

package com.zndroid.dm.FlyweightModel.impl;import com.zndroid.dm.FlyweightModel.BaseHero;/*** Created by luzhenyu on 2017/9/6.*/public class Arthur extends BaseHero {@Overridepublic String[] initKills() {return new String[]{"誓约之盾", "回旋打击", "圣剑裁决"};}@Overridepublic String getName() {return "亚瑟";}@Overridepublic String passiveKill() {return "圣光守护";}
}
package com.zndroid.dm.FlyweightModel.impl;import com.zndroid.dm.FlyweightModel.BaseHero;/*** Created by luzhenyu on 2017/9/6.*/public class HouYi extends BaseHero {@Overridepublic String[] initKills() {return new String[]{"炙热之风", "燎原箭雨", "惩戒射击"};}@Overridepublic String getName() {return "后羿";}@Overridepublic String passiveKill() {return "迟缓之箭";}
}
package com.zndroid.dm.FlyweightModel.impl;import com.zndroid.dm.FlyweightModel.BaseHero;/*** Created by luzhenyu on 2017/9/6.*/public class ZhuGeLiang extends BaseHero {@Overridepublic String[] initKills() {return new String[]{"东风破袭", "时空穿梭", "元气弹"};}@Overridepublic String getName() {return "诸葛亮";}@Overridepublic String passiveKill() {return "策谋之刻";}
}

核心在这,存储/新建英雄

package com.zndroid.dm.FlyweightModel;import com.zndroid.dm.FlyweightModel.impl.Arthur;
import com.zndroid.dm.FlyweightModel.impl.HouYi;
import com.zndroid.dm.FlyweightModel.impl.ZhuGeLiang;import java.util.HashMap;/*** Created by luzhenyu on 2017/9/6.*/public class HeroManager {private HashMap<String, BaseHero> map;private HeroManager(){map = new HashMap<>();}private static HeroManager manager = new HeroManager();public static HeroManager getManager() {return manager;}public BaseHero createHero(String name) {BaseHero hero = map.get(name);//用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象if (null == hero) {switch (name){case "亚瑟":hero =  new Arthur();break;case "诸葛亮":hero = new ZhuGeLiang();break;case "后羿":hero = new HouYi();break;}map.put(name, hero);}System.out.println("(这条消息请忽略:) " + name + "[" + hero.toString() + "]");return hero;}}

下面创建玩家:

package com.zndroid.dm.FlyweightModel.user;/*** Created by luzhenyu on 2017/9/6.*/import com.zndroid.dm.FlyweightModel.BaseHero;
import com.zndroid.dm.FlyweightModel.impl.HouYi;/**来表示玩家*/
public class Role {private long MP;private long HP;private String niceName;private BaseHero hero;public long getMP() {return MP;}public void setMP(long MP) {this.MP = MP;}public long getHP() {return HP;}public void setHP(long HP) {this.HP = HP;}public String getNiceName() {return niceName;}public void setNiceName(String niceName) {this.niceName = niceName;}public Role(BaseHero hero) {this.hero = hero;}public void releaseKill(int index) {System.out.println(getNiceName() + " use " + hero.releaseKills(index));}public void releaseCommonAttack() {System.out.println(getNiceName() + " use " + hero.commonAttack());}
}

来看一下使用:

/*** 享元模式* 它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;* 它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。* 常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。* 把一个对象可共享的状态给封装起来,而不可能共享的状态则从外部获取,享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象* 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象(用 HashMap 存储这些对象)。* 应用实例:JAVA 中的 String,数据库中的数据池* 使用场景: 1、系统有大量相似对象。 2、需要缓冲池的场景。* 注意事项: 1、注意划分外部状态和内部状态,否则可能会引起线程安全问题。 2、这些类必须有一个工厂对象加以控制。* *///现在王者荣耀辣么火,同一个服务器辣么多人,玩同一角色的玩家也是非常多的,假如说有100个玩家玩亚瑟,那么游戏需要创建100个亚瑟//分配给这100个玩家,如果10000个  1000000个呢? 想想就可怕, 明明就是同一个亚瑟这个英雄拿哪来这么多对象啊,多的也就是玩家,但是英雄不应该也这么多啊。//这样同一个服务器内存肯定吃不消,因此,享元模式可以解决这个问题,不就是同一个亚瑟吗,他们的基础属性(内部,不共享)都是一样的,区别在于玩家的血量不一样(外部共享)以及//玩家释放具体技能不一样(但是每个技能的效果亚瑟肯定都是一样的,具体释放哪个技能交给玩家决定好了)//匹配中...HeroManager manager = HeroManager.getManager();/**蓝方队伍*///玩家1进入,并选择英雄Role bRole1 = new Role(manager.createHero("后羿"));bRole1.setHP(1000);bRole1.setMP(1500);bRole1.setNiceName("蓝队玩家1");//玩家2进入,并选择英雄Role bRole2 = new Role(manager.createHero("亚瑟"));bRole2.setHP(0);bRole2.setMP(2500);bRole2.setNiceName("蓝队玩家2");//玩家3进入,并选择英雄Role bRole3 = new Role(manager.createHero("诸葛亮"));bRole3.setHP(1500);bRole3.setMP(2000);bRole3.setNiceName("蓝队玩家3");//....../**红方队伍*///玩家1进入,并选择英雄Role rRole1 = new Role(manager.createHero("后羿"));rRole1.setHP(1000);rRole1.setMP(1500);rRole1.setNiceName("红队玩家1");//玩家1进入,并选择英雄Role rRole2 = new Role(manager.createHero("诸葛亮"));rRole2.setHP(1500);rRole2.setMP(2000);rRole2.setNiceName("红队玩家2");//玩家1进入,并选择英雄Role rRole3 = new Role(manager.createHero("亚瑟"));rRole3.setHP(0);rRole3.setMP(2500);rRole3.setNiceName("红队玩家3");// 敌军还有5秒钟到达战场... //// 以下是酣畅淋漓的战斗bRole1.releaseKill(1);bRole1.releaseCommonAttack();rRole3.releaseKill(1);rRole3.releaseCommonAttack();rRole2.releaseKill(2);bRole2.releaseCommonAttack();bRole2.releaseKill(0);rRole1.releaseCommonAttack();rRole1.releaseKill(0);bRole3.releaseKill(2);// ACE// 6分投吧~~~~log("----------------我是分割线-----------------");

运行结果:

[ ======================================== ]
(这条消息请忽略:) 后羿[com.zndroid.dm.FlyweightModel.impl.HouYi@42a57993]
(这条消息请忽略:) 亚瑟[com.zndroid.dm.FlyweightModel.impl.Arthur@75b84c92]
(这条消息请忽略:) 诸葛亮[com.zndroid.dm.FlyweightModel.impl.ZhuGeLiang@6bc7c054]
(这条消息请忽略:) 后羿[com.zndroid.dm.FlyweightModel.impl.HouYi@42a57993]
(这条消息请忽略:) 诸葛亮[com.zndroid.dm.FlyweightModel.impl.ZhuGeLiang@6bc7c054]
(这条消息请忽略:) 亚瑟[com.zndroid.dm.FlyweightModel.impl.Arthur@75b84c92]
蓝队玩家1 use 后羿 release 燎原箭雨 + 被动 迟缓之箭 biu biu biu ~
蓝队玩家1 use 后羿 release 物理攻击 kua kua kua ~
红队玩家3 use 亚瑟 release 回旋打击 + 被动 圣光守护 biu biu biu ~
红队玩家3 use 亚瑟 release 物理攻击 kua kua kua ~
红队玩家2 use 诸葛亮 release 元气弹 + 被动 策谋之刻 biu biu biu ~
蓝队玩家2 use 亚瑟 release 物理攻击 kua kua kua ~
蓝队玩家2 use 亚瑟 release 誓约之盾 + 被动 圣光守护 biu biu biu ~
红队玩家1 use 后羿 release 物理攻击 kua kua kua ~
红队玩家1 use 后羿 release 炙热之风 + 被动 迟缓之箭 biu biu biu ~
蓝队玩家3 use 诸葛亮 release 元气弹 + 被动 策谋之刻 biu biu biu ~
[ ----------------我是分割线----------------- ]
[ ======================================== ]

【欢迎上码】

【微信公众号搜索 h2o2s2】

设计模式之——享元设计模式相关推荐

  1. 结构设计模式 - Flyweight设计模式(享元设计模式)

    结构设计模式 - Flyweight设计模式 今天我们将研究Flyweight 设计模式,Flyweight设计模式又被称为 享元设计模式 . 目录[ 隐藏 ] 1 Flyweight设计模式 1.1 ...

  2. java设计模式之享元设计模式

    一.构成 单纯享元模式 抽象享元角色:定义了公共的接口,所有的具体享元角色需要实现的接口,那些需要外蕴状态的操作可以通过方法的参数传入. 具体享元角色:实现抽线享元角色所规定的公共接口,如果有内蕴状态 ...

  3. Java设计模式(十八):享元设计模式

    1. 应用场景 当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空 ...

  4. Integer注意_享元设计模式

    public class IntegerNote{ public static void main(String[] args){   Integer d1=100;   Integer d2=100 ...

  5. 设计模式:享元(FlyWeight)模式

    设计模式:享元(FlyWeight)模式 一.前言     享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象.如何共享对象,那就是在检测对象产生的时候 ...

  6. 北风设计模式课程---享元模式

    北风设计模式课程---享元模式 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 1.享元模式的本质是什么? 池技术:各种缓存池都是享元模式的体现 说到享元模 ...

  7. python设计模式之享元模式

    一.享元模式定义: 享元模式是一种用于解决资源和性能压力时会使用到的设计模式,它的核心思想是通过引入数据共享来提升性能. 在开发3D游戏时,例如有成千上万的士兵或者有成千上万棵树,如果一个3D地带的每 ...

  8. 每天一个设计模式之享元模式

    作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) ...

  9. 北风设计模式课程---享元模式与单例模式区别

    北风设计模式课程---享元模式与单例模式区别 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 1.享元模式与单例模式区别? 级别:单例模式是类级别的,一个类 ...

最新文章

  1. 设置VSCode终端命令行清除快捷键Ctrl+K或Ctrl+L
  2. python3 字符串总结
  3. python项目实战:获取本机所有IP地址的方法
  4. 特征选择与特征权重区别
  5. Linux命令必知必会
  6. verilog仿真——$test$plusargs 和 $value$plusargs
  7. Class Diagram
  8. LeetCode 1071. 字符串的最大公因子(字符串的最大公约数)
  9. OFD文件结构--带签名
  10. Linux下新手基本操作及技巧看图上路 (7)
  11. python可选参数定义_Python中函数的参数定义和可变参数用法实例分析
  12. 台位数量超过9时,知识竞赛软件如何进行前期设置?
  13. 美团财报数据初步分析
  14. 山西台达plc可编程控制器_可编程控制器(PLC)故障的常见原因及处理方法
  15. 手机怎样和宽带连接无线路由器设置路由器连接服务器,手机如何设置路由器?...
  16. PPT到WORD的组合图片复制
  17. 酷Q机器人,QQ机器人使用教程
  18. xyoj 6042:让人头疼的“双十一”
  19. 2017前端精品面试文章总结
  20. viewFlipper的基本实现

热门文章

  1. js递归函数及深浅拷贝
  2. 没有真心,谈何珍惜!
  3. 转:Unix传奇(下篇)
  4. 淘宝API 商品详情接口
  5. AP 计算机 华丽逆袭-----被麻省理工计算机博士老师反复劝退的学生逆袭的肺腑之言
  6. winsock chapter6 - 地址家族和名字解析
  7. SPI和IIC通信区别
  8. Redrain仿酷狗音乐播放器开发完毕,发布测试程序
  9. UOS软件安装相关命令
  10. 计算机科学与技术考研学校排名及录取分数线,计算机专业考研学校全国排名及各高校复试分数线.pdf...