定义:

采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。

享元的英文是flyweight,是一个来自体育方面的专业用语,在拳击、摔跤和举重比赛中特指最轻量的级别。把这个单词移植到软件工程中,也是用来表示特别小的对象,即细粒度的对象。至于为什么把flyweight翻译为享元,可以理解为共享元对象,也就是共享细粒度对象。

享元模式中区分了内蕴状态和外蕴状态。内蕴状态不能改变,是可以共享的。外蕴状态是可以的改变的,不能共享,由客户端保持。

模式组成:

  • Flyweight: 抽象享元类。所有具体享元类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部专题
  • ConcreteFlyweight: 具体享元类。指定内部状态,为内部状态增加存储空间
  • FlyweightFactory:

    享元工厂类。用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)。

uml类图:



模式分类:

  • 单纯享元模式(即该对象没有外蕴状态,整个对象可以共享,类似于单例模式)
  • 复合享元模式(该对象有内蕴状态,也有外蕴状态,内蕴状态共享)

优点:

  • 极大的减少系统中对象的个数,节省内存的开销
  • 避免创建过多的对象,提升性能

缺点:(这也算缺点?有待考究)

  • 由于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了
  • 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长


应用场景:

  • 存在大量重复对象的场景

在Java中,lang包下的Integer类,对于经常使用的-128
到 127 范围内的Integer对象当类一被加载时就被创建了,并保存在cache数组中,一旦程序调用valueOf
方法,如果i的值是在-128 到 127 之间就直接在cache缓存数组中去取Integer对象而不是创建一个新对象,这就是享元模式的应用。

      • java.lang.Integer#valueOf(int)
      • java.lang.Boolean#valueOf(boolean)
      • java.lang.Byte#valueOf(byte)
      • java.lang.Character#valueOf(char)

举个栗子:

定义抽象享元角色

abstract class Dish {
public abstract void desc();
}

定义具体享元角色

class ButterMoshroom extends Dish {
public String taste; public ButterMoshroom(String taste) {
this.taste = taste;
} @Override
public void desc() {
System.out.println(taste + "酱野山菌");
}
}

定义工厂

class ButterMoshroomFactory {
static Map<String, Dish> dishes = new HashMap<String, Dish>(); public synchronized static Dish getDish(String taste) {
Dish dish = dishes.get(taste);
if (dish == null) {
dish = new ButterMoshroom(taste);
}
dishes.put(taste, dish);
return dish;
}
}

客户端调用

public static void main(String[] args) {
ButterMoshroomFactory.getDish("xo").desc();
ButterMoshroomFactory.getDish("番茄").desc();
}

输出

享元模式(Flyweight Pattern)的更多相关文章

  1. 二十四种设计模式:享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...

  2. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  3. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

  4. 设计模式-11享元模式(Flyweight Pattern)

    1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...

  5. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  6. 七个结构模式之享元模式(Flyweight Pattern)

    定义: 运用共享技术对大量细粒度对象的复用,这要求这些对象都很相似,状态变化很小.将这些对象的内部状态和外部状态进行区分,对于内部状态相同的只存储一个对象,而对不同的外部状态则采用不同的操作. 结构图 ...

  7. 【UE4 设计模式】享元模式 Flyweight Pattern

    概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...

  8. 12.享元模式(Flyweight Pattern)

    using System; using System.Collections; namespace ConsoleApplication5 { class Program { /// <summ ...

  9. 享元模式<Flyweight Pattern>

    1.What-是什么?   享元模式是一种轻量级的结构型模式.旨在以共享的方式高效的支持大量的细粒度对象的复用.要求能够共享的对象必须是细粒度对象,这些对象比较相似,状态变化小. 2.Why-为什么? ...

随机推荐

  1. Java自学-异常处理 自定义异常

    Java 自定义异常 示例 1 : 创建自定义异常 一个英雄攻击另一个英雄的时候,如果发现另一个英雄已经挂了,就会抛出EnemyHeroIsDeadException 创建一个类EnemyHeroIs ...

  2. MySQL里默认的几个库是干啥的?

    本文涉及:MySQL安装后自带的4个数据库:information_schema. performance_schema.sys.mysql的作用及其中各个表所存储的数据含义 information_ ...

  3. Shell中根据svn是否有待更新的版本去决定是执行maven打包

    1- svn 更新判断代码 本着学习的目的,这里使用了两种获取version的方法. localVersion=$(svn info -R | grep "Revision\:" ...

  4. 你遇到过哪些原因造成MySQL异步复制延迟?

    master上多为并发事务,salve上则多为单线程回放(MySQL 5.7起,支持真正的并行回放,有所缓解) 异步复制,本来就是有一定延迟的(否则也不叫做异步了,介意的话可以改成半同步复制) sla ...

  5. Win10下免安装版MySQL8.0.16的安装和配置

    1.MySQL8.0.16解压 其中dada文件夹和my.ini配置文件是解压后手动加入的,如下图所示 2.新建配置文件my.ini放在D:\Free\mysql-8.0.16-winx64目录下 [ ...

  6. java 时间格式

    自定义时间格式:yyyy 年MM 月dd 天HH 24小时制hh 12小时制mm 分钟ss 秒 java.util.Date日期格式为:年月日时分秒 java.sql.Date日期格式为:年月日jav ...

  7. PostgreSQL分区表实现——pg_pathman分区表管理

    该博文用于自己学习记录,内容节选自: https://github.com/digoal/blog/blob/master/201610/20161024_01.md pg_pathman 创建分区表 ...

  8. PAT 乙级 1008.数组元素循环右移问题 C++/Java

    1008 数组元素循环右移问题 (20 分) 题目来源 一个数组A中存有N(>)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥)个位置,即将A中的数据由(A​0​​A​1​​⋯ ...

  9. el-tabs 使用

    el-tabs 使用 文章标题 网址 https://www.cnblogs.com/yuxiaole/p/9523735.html https://www.jianshu.com/p/571d832 ...

  10. cmds在线重定义增加列

    --输出信息采用缩排或换行格式化 EXEC DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'PRETTY', T ...