文章目录

  • 一、基本介绍
    • 1、定义
    • 2、优点
    • 3、缺点
    • 4、角色
      • 1)抽象享元类
      • 2)具体享元类
      • 3)享元工厂类
      • 4)组合享元类
    • 5、内部状态和外部状态
  • 二、应用情景
    • 1、线程池
    • 2、String
    • 3、Integer
    • 4、五子棋
  • 三、与其他模式的搭配使用
    • 1)单例模式
    • 2)组合模式
    • 3)工厂模式
  • 四、代码解析

一、基本介绍

1、定义

享元模式(FlyWeight),又称为蝇量模式,常用于有着大量重复使用的细粒度对象时。实质上是一种共享技术。

2、优点

利用享元池,可以使得用户在调用一个对象时可以不必去new,只需要在享元池中直接获取即可,节约了内存空间。
注:太多的对象不仅会影响性能,更严重的情况下可能会造成内存溢出

3、缺点

1)逻辑会更加的复杂。
2)对于一些享元池中不能直接取出的对象,还是需要去new,这时利用了享元模式获取对象的时间会变得更长。

4、角色

1)抽象享元类

接口/抽象类

2)具体享元类

实现接口或者抽象类的具体子类,这些子类会被大量的重复使用,而且这些子类对象都是细粒度。

3)享元工厂类

工厂其实就是一个享元池

4)组合享元类

组合享元类是依赖基本享元类产生的一个整体类,例如享元池中,如果有字符A、B,我们其实可以利用这两个字符对象构成一个AB字符串,这就是一个组合享元类。

5、内部状态和外部状态

细粒度对象,当对象数量较多时不可避免性质相似,如何区分如此多的不同的细粒度对象呢?此时我们就将这些对象的信息分为两个部分:内部状态和外部状态。

  • 内部状态指对象共享出来的信息,存储在享元对象内部并且不会随环境的改变而改变;
  • 外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。
                 如何理解内部状态和外部状态呢?

比如坦克大战中,有着不同类型的子弹,这些子弹就是因为内部状态的不同而改变的,例如是燃烧弹还是烟雾弹就是看其内部状态了。但是我们的坦克可以朝着不同的方向发射子弹,子弹的方位坐标就是子弹的一个外部状态了。

再比如为围棋,只有黑白两颗子,内部状态控制颜色,而外部状态控制棋在棋中的位置。

二、应用情景

1、线程池

2、String

在JVM中有一个字符串常量池,例如,当String=“a"时,并不是直接在堆中new String("a"),而是会先去常量池中进行查询,如果常量池中有“a”,则直接会返回常量池中字符串"a"的引用地址。字符串相加,其实是调用了StringBuilder()的append,然后再toString,所以相加后的引用不在常量池而在堆中。

3、Integer

在Integer中,也有一些已经存在的对象(-128,127),这些对象被放入缓冲区中,当我们用Integer a=1;或者Integer a=Integer.ValueOf(1)时,就会先与缓冲区中的对象相匹配,如果缓冲区有,则直接返回缓冲区中的对象,没有的话,例如128在缓冲区没有,就只能return Integer a=new Integer(128);

4、五子棋

在五子棋游戏中,如果共需要500多颗黑白子,那么在没有利用享元模式或者单例模式时,我们就必须要new500多个对象,然而,如果利用享元模式,就可以只有两个对象:一个黑棋,一个白棋。[注:单例模式也可以实现],这样极大的节省了内存的空间,也节省了new的时间,空间和时间性能都有着极大的提升。

三、与其他模式的搭配使用

享元模式通常与单例模式组合模式工厂模式搭配使用。

1)单例模式

工厂可以使用单例模式.(前提是工厂不是泛型工厂)

2)组合模式

复合的享元模式是使用了组合模式的

3)工厂模式

工厂其实就是一个享元池

四、代码解析

//抽象享元

package pattern.flyweight;public abstract class FlyWeight {//内部状态
String instate;
//外部状态
String outstate;
public FlyWeight(String outstate) {this.instate=outstate;
}
//与外部状态相关的逻辑操作
abstract void operation();
//获取或者设置内部状态
public String getInstate() {return instate;
}
public void setInstate(String instate) {this.instate = instate;
}}

//具体享元

package pattern.flyweight;
public class A extends FlyWeight{public A(String outstate) {super(outstate);// TODO Auto-generated constructor stub}
//根据外部状态进行一系列的逻辑操作@Overridevoid operation() {// TODO Auto-generated method stubSystem.out.println(outstate);}}

//享元工厂

package pattern.flyweight;import java.util.HashMap;
import java.util.Map;//泛型时,不能用单例模式,否则泛型将会没有意义
public class FlyWeightFactory {private FlyWeightFactory() {};
// volatile是避免重排序
private static volatile FlyWeightFactory INSTANCE = null;public static FlyWeightFactory getINSTANCE() {if (INSTANCE == null) {synchronized (FlyWeightFactory.class) {if (INSTANCE == null)INSTANCE = new FlyWeightFactory();}}return INSTANCE;
}static Map<Character,FlyWeight> FlyWeightMap=new HashMap<Character,FlyWeight>();public  FlyWeight getConcreteFlyWeight(char c) {if(!FlyWeightMap.containsKey(c))FlyWeightMap.put(c,new A());return FlyWeightMap.get(c);
}
}

//测试类

package pattern.flyweight;
public class Main {public static void main(String[] args) {/** Integer a=Integer.valueOf(3);//有缓存机制 Integer c=new Integer(3);//没有用到缓存机制* Integer b=new Integer(3); Integer d=3;//有用到缓存机制 Integer e=129; Integer* f=129;//超过了缓存池 System.out.println(a==d); System.out.println(e==d);* System.out.println(c==b);* * String a0="a"; String a1="b"; String a2="a"+"b"; String b="ab"; String* c="ab"; String a=a0+a1;* System.out.println(a==b);//字符串相加其实是StringBuilder.append()然后toString* System.out.println(a.intern()==b);//intern是找常量池中的引用* System.out.println(b==c);//两个都指向常量池中* System.out.println(a2==b);//如果是定义的时候直接相加,编译器会进行优化,直接看成String a2="ab";*/FlyWeight a=FlyWeightFactory.getINSTANCE().getConcreteFlyWeight('a',"outstate");FlyWeight b=FlyWeightFactory.getINSTANCE().getConcreteFlyWeight('a',"outstate");System.out.println(a==b);}
}


UML图:

几行代码真的很难说清享元模式,而且也没有找到比较合适的例子,所以只能在这里简单介绍了基本享元模式,文中测试也只测试了a和b是否是指向同一引用,在一些规模比较小的程序中享元模式的优点真的是很难体现出来,如果还是有很多疑惑可以去查看java源码,线程池和Integer的缓冲区等都非常牛的运用了享元模式。

java23设计模式---class10、享元模式(FlyWeight)相关推荐

  1. 设计模式之享元模式(Flyweight)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  2. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  "享"取"共享"之意,"元"取"单元"之意. 意图 运用共享技术,有效的支持大量细粒度 ...

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

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

  4. 设计模式(十)享元模式Flyweight(结构型)

    设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...

  5. 设计模式(18):结构型-享元模式(Flyweight)

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  6. 【设计模式自习室】享元模式 Flyweight Pattern:减少对象数量

    前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...

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

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

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

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

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

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

最新文章

  1. Qt QDialog将窗体变为顶层窗体(activateWindow(); 和 raise() )
  2. Oracle为什么装在XP系统,重装xp系统后oracle恢复方法
  3. 在Linux下查看环境变量
  4. 【Python】Python海龟绘图秀场
  5. 人脸关键点:MTCNN-Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks
  6. 蓝桥杯 PREV-5历届试题 错误票据
  7. 12.swoft 安装
  8. 设计模式-第六篇之策略模式
  9. Centos 7安装Zabbix6.0
  10. FL studio 20简易入门教程 -- 第七篇 -- 音频、音源与音色
  11. 永磁同步电机数学模型
  12. 【翻译】CRAFT:Character Region Awareness for Text Detection
  13. 通过Mixamo生成人物动画并导入Unity实现资源可用的方法
  14. 深入理解安卓异步任务AsyncTask
  15. 记录各大牛个人主页,紧密跟踪其学术动态
  16. poi对word读取(文本和图片)、修改、保存操作及word转换为PDF
  17. 2021-03-14 JavaWeb实验课
  18. postgres内存上下文
  19. 已拿 Offer!字节跳动面试经验分享
  20. MTK |Android KKL 平台TP调试

热门文章

  1. 赛效:怎么用转转大师快捷转换文件格式
  2. 81章 老子1章到_老子道德经第八十一章原文及译文
  3. 基于C#简单实现的微信网页版接口
  4. 网站开发————JavaEE/实训实训实训
  5. objc - 编译Runtime源码objc4-680
  6. 信用卡逾期多少天会成为黑户?
  7. 钉钉 阿里 The request signature we calculated does not match the signature you provide
  8. 私域流量+小程序,电商引流新机会
  9. Ubuntu 16.04 安装nvidia驱动
  10. 鱼蛋分类及加盟注意事项