作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可。

魔都。

自从越狱风波过去以后,小左的生活便又回到了之前的节奏,依旧是每日徘徊在魔都某天桥,继续着自己的算命之旅。

说起这次越狱风波,着实让小左心情沉闷了很久。原因无他,就是因为在施展一次记忆恢复的过程中,发生了一点意外,结果导致一名看守所人员的记忆产生了混乱,如果用通俗的话来讲,就是变成了人们口中常说的精神病。

小左当时选择的是一个生物专业硕士毕业的应届生的记忆,而另外一位被注入记忆的看守所成员,已经成功了迈入了生物界的神奇领域,虽说谈不上一步登天,但相信现在生活的应该要比之前在看守所好上数倍。当然,这番生活条件的改观也并非白来的,这位新生的生物界奇才,所失去的,正是之前数十年的记忆,这之中也当然包括了对家人朋友的记忆。

至于故事当中的主角韩雨露,此时应该已经被其能力通天的父亲给保护了起来。自从韩雨露被小左私自释放,除了刚开始的新闻漫天之外,短短的十数天,此事就像是没有发生过一样烟消云散。尽管这是小左意料之中的,否则小左也不会义无反顾的释放韩雨露,不过之前小左可远远没有想到消息的封锁会如此之快。

值得一说的是李刚和李双江,自从被误认为私自释放了韩雨露,二人的生活就直接陷入了暗无天日的境地,虽说这样的结果对二人有些不公平,不过由于二人对韩雨露语言上的亵渎,导致小左并未对此有所愧疚。

魔都某网吧。

“尼玛,辅助买个鸟啊。”小左坐在烟雾缭绕的网吧里,骂骂咧咧的大声喊道。细一看,就发现小左在叫骂的同时,正拉着自己红血的SF马不停蹄的往泉水跑。

............

“我考,不带这么玩的吧。”

只见小左的电脑屏幕之上,三道红光一闪即逝,小左的SF瞬间倒地,在释放一记魂之挽歌之后,便不甘的回到了泉水。

“SF,你TM会不会啊,别出门了行不?”

“9494,你这么送下去,我们还怎么玩啊。”

“猪一样的队友啊,真TM倒霉。”

..........

看着屏幕上陆续浮现出的队友们的谩骂,小左终于忍受不了,无奈的看了看自己40分钟依旧是假腿的SF,匆匆的退出了游戏。

魔都某出租屋。

“好不容易想起去体验几把DOTA,结果全跪了。尼玛,太不爽了。不行,我得虐虐电脑,找找快感。”

由于被连续虐了几把,小左回到家里依旧感觉十分不爽,于是便再次打开DOTA,准备虐几把电脑找找感觉。

机器始终不是人类,在连续几把无限超神之后,小左终于感觉心里舒畅了许多。无聊之际,开始漫无目的的在网上冲浪。不过由于小左转生之前毕竟是一名程序猿,所以看着看着,不知不觉之间便打开了享元模式的定义。

定义:享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

“看定义的意思,这个模式主要是为了减少不必要的重复对象,减少内存消耗。而要做到这个的话,那么就需要把一个对象可共享的状态给封装起来,而不可能共享的状态则从外部获取。”

小左指尖不停的敲打着桌面,继续说道:“如果所有DOTA的玩家都在一台服务器上操作,那么DOTA里的英雄应该就可以使用享元模式。每一个英雄应该都是唯一的实例,而不应该是一旦有人选了一个英雄,就要实例化一个。”

“如果是传统意义上的方式,应该是这种写法。假设有一个抽象的英雄基类。”

package com.flyweight;//抽象英雄基类
public abstract class AbstractHero {protected final String name;//英雄名称protected final String[] skills = new String[4];//每个英雄都有四个技能protected long hp;//血量protected long mp;//魔法public AbstractHero() {super();this.name = getName();initSkills();checkSkills();}private void checkSkills(){for (int i = 0; i < skills.length; i++) {if (skills[i] == null) {throw new NullPointerException();}}}//释放技能public void release(int index){if (index < 0) {index = 0;}else if (index > 3) {index = 3;}System.out.println(name + "释放" + skills[index]);} //物理攻击public void commonAttack(){System.out.println(name + "进行物理攻击");}public abstract String getName();public abstract void initSkills();public long getHp() {return hp;}public void setHp(long hp) {this.hp = hp;}public long getMp() {return mp;}public void setMp(long mp) {this.mp = mp;}}

“英雄可以释放技能,物理攻击等等,而且英雄是有血量和魔法量的。下面就写两个具体的英雄看一下。”

package com.flyweight;public class Lion extends AbstractHero{public String getName() {return "恶魔巫师";}public void initSkills() {skills[0] = "穿刺";skills[1] = "妖术";skills[2] = "法力汲取";skills[3] = "死亡一指";}}

package com.flyweight;public class SF extends AbstractHero{public String getName() {return "影魔";}public void initSkills() {skills[0] = "毁灭阴影";skills[1] = "支配死灵";skills[2] = "魔王降临";skills[3] = "魂之挽歌";}}

“一个恶魔巫师,一个影魔。很显然,假设现在有四个solo局,都是SF对LION,那么现在这种方式则需要实例化四个LION和四个SF。就像下面这样。”

package com.flyweight;public class Main {public static void main(String[] args) {//假设有四个solo局,则需要创建四个lion和四个sfLion lion1=new Lion();SF sf1 = new SF();Lion lion2=new Lion();SF sf2 = new SF();Lion lion3=new Lion();SF sf3 = new SF();Lion lion4=new Lion();SF sf4 = new SF();/* 以下为释放技能,物理攻击等的打架过程  */}}

“这样显然是非常浪费资源啊,四个lion和四个sf其实是有很多一样的地方的。这应该就可以使用享元模式了吧。”

“不过享元模式强调内部状态和外部状态,内部状态则是可以共享的状态,外部状态则是随外部环境而变化的状态,是无法共享的状态。那么下面要做的就是将外部状态分离出来,只保留内部状态,这样的话对象的实例就可以共享了。”

“啪!”

小左打了个响指,继续说道:“对于上面DOTA英雄的简单例子来说,血量和魔法量应该是外部状态了,因为四个solo局中,每个lion和每个sf的血量和魔法量不一定是相等的,所以这两个状态是无法共享的。但是技能和名称就不一样了,它们俩应该属于内部状态,是可以共享的,因为不管是哪个solo局里的lion或者sf,它们的英雄名称和技能都是一样的。”

“这下好办了,首先应该把基类里面的血量和魔法量删掉。”

package com.flyweight;//抽象英雄基类
public abstract class AbstractHero {protected final String name;//英雄名称protected final String[] skills = new String[4];//每个英雄都有四个技能public AbstractHero() {super();this.name = getName();initSkills();checkSkills();}private void checkSkills(){for (int i = 0; i < skills.length; i++) {if (skills[i] == null) {throw new NullPointerException();}}}//释放技能public void release(int index){if (index < 0) {index = 0;}else if (index > 3) {index = 3;}System.out.println(name + "释放" + skills[index]);} //物理攻击public void commonAttack(){System.out.println(name + "进行物理攻击");}public abstract String getName();public abstract void initSkills();}

“其余的两个子类应该是不用变的,下面我还需要再写一个类去组合英雄的内部状态和外部状态。”

package com.flyweight;
//用于组合英雄内部状态和外部状态的类,假设称为角色
public class Role {private AbstractHero hero;//角色选择的英雄//我们把血量和魔法量这两个外部状态从英雄里剥离出来,放到外部的角色类中private long hp;private long mp;public Role(AbstractHero hero) {super();this.hero = hero;}//释放技能public void release(int index){hero.release(index);} //物理攻击public void commonAttack(){hero.commonAttack();}public long getHp() {return hp;}public void setHp(long hp) {this.hp = hp;}public long getMp() {return mp;}public void setMp(long mp) {this.mp = mp;}}

“我们用角色这个类去组合英雄的内部和外部状态,下面还需要一个享元模式最重要的类,就是提供共享功能的类。”

package com.flyweight;import java.util.HashMap;
import java.util.Map;
//提供共享功能,单例
public class HeroManager {private static HeroManager heroManager = new HeroManager();private Map<String, AbstractHero> heroMap;private HeroManager(){heroMap = new HashMap<String, AbstractHero>();}public static HeroManager getInstance(){return heroManager;}//该方法提供共享功能public AbstractHero getHero(String name){AbstractHero hero = heroMap.get(name);if (hero == null) {if (name.equals("恶魔巫师")) {hero = new Lion();}else if (name.equals("影魔")) {hero = new SF();}heroMap.put(name, hero);}return hero;}
}

“现在如果再来四个solo局,那么情况就和刚才不太一样了。”

package com.flyweight;public class Main {public static void main(String[] args) {//假设有四个solo局,则使用了享元模式的情况下,其实恶魔巫师和影魔的实例各自只有一个HeroManager heroManager = HeroManager.getInstance();Role role1 = new Role(heroManager.getHero("恶魔巫师"));Role role2 = new Role(heroManager.getHero("影魔"));Role role3 = new Role(heroManager.getHero("恶魔巫师"));Role role4 = new Role(heroManager.getHero("影魔"));Role role5 = new Role(heroManager.getHero("恶魔巫师"));Role role6 = new Role(heroManager.getHero("影魔"));Role role7 = new Role(heroManager.getHero("恶魔巫师"));Role role8 = new Role(heroManager.getHero("影魔"));/* 以下为释放技能,物理攻击等的打架过程  */}}

“四个solo局当中有八个角色,选了八个英雄,四个lion和四个sf,但是很明显,使用了享元模式之后,这里面的八个英雄其实只有一个lion实例和一个sf实例,这样就大大减少了英雄的实例个数。试想一下,如果同时有1000个solo局,按照之前的方式,那么会有1000个lion的实例和1000个sf的实例,而现在使用享元模式的话,依旧是只有一个lion实例和一个sf实例。”

“这么说起来的话,享元模式节省的内存实在是不可估量啊。只不过DOTA这么大型的游戏,它的设计应该不会这么简单,不过用来理解享元模式还是个不错的例子啊,哈哈。”
                理解了享元模式的好处,小左像打了鸡血似的,一拍桌子大叫道:“NND,再去网吧搞两把。”

话音刚落,小左便一溜烟跑出了出租屋,直奔网吧而去。

转载于:https://www.cnblogs.com/haoerlv/p/7772702.html

设计模式之- 享元模式详解(都市异能版)相关推荐

  1. 设计模式之享元模式详解

    设计模式之享元模式详解 概述 享元模式定义: ​ 运用共享技术来有效地支持大量细粒度对象的复用.它==通过共享已经存在的对象来大幅度减少需要创建的对象数量==.避免大量相似对象的开销,从而提高系统资源 ...

  2. (十八)享元模式详解(都市异能版) - 转

    作者:zuoxiaolong8810(左潇龙),转载请注明出处. 魔都. 自从越狱风波过去以后,小左的生活便又回到了之前的节奏,依旧是每日徘徊在魔都某天桥,继续着自己的算命之旅. 说起这次越狱风波,着 ...

  3. (十八)享元模式详解(都市异能版)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处. 魔都. 自从越狱风波过去以后,小左的生活便又回到了之前的节奏,依旧是每日徘徊在魔都某天桥,继续着自己的算命之旅. 说起这次越狱风波,着 ...

  4. Java设计模式之享元模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  5. 详解设计模式:享元模式

    享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式. 享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能.它提供了 ...

  6. 走穿java23种设计模式-15责任链模式详解

    走穿java23种设计模式-15责任链模式详解 责任链模式是一种常见的行为模式. 一.责任链模式的现实场景 习伟过生日邀请了很多朋友到KTV一起庆祝,为了增加欢乐的气氛,习伟建议大家一起玩击鼓传花的游 ...

  7. 走穿java23种设计模式--18中介者模式详解

    走穿java23种设计模式–18中介者模式详解 中介者模式也称调停者模式,是一种比较简单的模式. 一.中介者模式的现实场景 蔡良因为上次表白时对方只看重他的物质方面,所以他对女朋友这个问题有点失望.因 ...

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

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

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

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

最新文章

  1. 扩增子和宏基因组数据分析流程和可视化方案—刘永鑫(南京,2020年11月27日)
  2. Oracle数据库表设计时的注意事项
  3. 计算机病毒是什么文件形式,【文件病毒】文件病毒的格式、危害、特点_什么是文件病毒_佰佰安全网...
  4. effective c++ 条款20:宁以pass-by-reference-to-const替换pass-by-value
  5. StringBuilder与StringBuffer比较
  6. linux之task_struct
  7. 怎么在delphi显示html,如何在Delphi中将简单的RichText转换为HTML标签?
  8. freenas共享指定网络密码不正确_FreeNas系统安装贴心教程(附常见问题解决方案)...
  9. Python——KNN实战(附详细代码与注解)
  10. Java面试题和答案
  11. 内容管理项目小结 成功案例-公司官网,游戏官网
  12. Monkey Test - 命令
  13. Windows 10 常用软件推荐
  14. 外观检验人员一致性(Kappa)分析
  15. 蓝凌OA 漏洞学习——treexml.tmpl 远程命令执行漏洞
  16. 【下载源码】在线生成网页缩略图.超越Snap.com:WebSnap Beta 1.1 发布。感谢博客园的“萧寒”重写的底层。开源。
  17. MAC设置L2TP连接公司内部网络
  18. 。。。。。。。。。。。。。
  19. IDM(Internet Download Manager)下载器使用
  20. 台湾百张最佳专辑Mp3下载

热门文章

  1. 如何给自己的公众号引流的八种方法《知乎篇》
  2. rel=stylesheet
  3. 线上商城系统有哪些类型?
  4. Vue.prototype的使用
  5. 微信支付、支付宝支付回调处理总结
  6. 数据压缩(一)——计算机编程中的各种数据类型,以C为例
  7. 求购世界杯真品球衣购买地址一枚
  8. LNMP搭建+论坛搭建
  9. 马化腾谈互联网产品创新
  10. 记一次为学校流浪猫开发的小程序——航海之猫