1、模式简介

  当系统中存在大量对象时,非常容易造成内存溢出。为了解决这个问题,我们把这些对象中共有的部分抽象出来,如果有相同的业务请求,则直接返回在内存中已有的对象,避免重新创建,这就是享元模式。

  享元模式(FlyweightPattern)主要用于减少创建对象的数量,以减少内存占用和提高性能,即它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

  例如,JAVA中的String使用的就是享元模式:

public class Test {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
System.out.println(a == b);
}
}
// 返回值:true

  又如,一个编辑器中如果只能输入大小写的字母,则有52个字符可以输入,此时我们只需要在编辑器中存储52个字符对象,而不需要每输入一个字符就创建一个对象。

  享元模式的UML图:

享元模式的适用场景:

  • 当系统中有大量对象时;
  • 当这些对象基本相似时;
  • 当这些对象会消耗大量内存时;
  • 当这些对象需要使用缓冲池管理时。

享元模式的使用方法:

  享元模式通常使用一个工厂管理,在工厂中维护一个HashTable或HashMap,使用唯一标识来存放和取出对象。另外还可以对工厂使用单例模式,保证项目中只有一个工厂。

享元模式的优点:

  大大减少了对象的创建,降低了系统的内存,提高了效率。

享元模式的缺点:

  提高了系统的负责度,需要分离出外部状态和内部状态,外部状态不应该随着内部状态的变化而变化,否则会造成系统的混乱。

2、实例

  我们以上面说的编辑器的例子为需求,要求编辑器中只能输入字符,使用享元模式进行管理。

  享元接口:

public interface MyChar {
String showMyChar();
}

  享元实现类:

public class MyCharImpl implements MyChar {
private Character c; public MyCharImpl(Character c) {
this.c = c;
} @Override
public String showMyChar() {
return this.c + "";
}
}

  享元工厂:

public class MyCharFactory {
private static MyCharFactory instance; private Map<Character, MyChar> charMap; private MyCharFactory() {
this.charMap = new HashMap<Character, MyChar>();
} /**
* 单例
*/
public static MyCharFactory getInstance() {
if (instance == null) {
synchronized (MyCharFactory.class) {
if (instance == null) {
instance = new MyCharFactory();
}
}
}
return instance;
} /**
* 根据字符的键获取字符对象
*/
public MyChar getMyChar(Character character) {
MyChar c = charMap.get(character);
if (c == null) {
c = new MyCharImpl(character);
charMap.put(character, c);
}
return c;
} /**
* 获取Map中存储的字符的数量
*/
public int getCharCount() {
return charMap.size();
}
}

  测试类:

public class Test {
public static void main(String[] args) {
MyChar char1;
MyChar char2;
MyChar char3;
MyChar char4;
MyChar char5;
MyChar char6; char1 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char1.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char2 = MyCharFactory.getInstance().getMyChar(new Character('b'));
System.out.println("获取享元字符:" + char2.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char3 = MyCharFactory.getInstance().getMyChar(new Character('c'));
System.out.println("获取享元字符:" + char3.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char4 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char4.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char5 = MyCharFactory.getInstance().getMyChar(new Character('a'));
System.out.println("获取享元字符:" + char5.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
char6 = MyCharFactory.getInstance().getMyChar(new Character('d'));
System.out.println("获取享元字符:" + char6.showMyChar());
System.out.println("当前享元字符数量:" + MyCharFactory.getInstance().getCharCount());
}
}

  运行结果如下图所示:

  最后贴出享元模式的GitHub代码地址:【GitHub - FlyWeight】

【设计模式 - 11】之享元模式(FlyWeight)的更多相关文章

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

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

  2. 设计模式学习心得<享元模式 Flyweight>

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

  3. 《JAVA设计模式》之享元模式(Flyweight)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是 ...

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

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

  5. 第11章 享元模式(Flyweight Pattern)

    原文 第11章 享元模式(Flyweight Pattern) 概述:   面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时 ...

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

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

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

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

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

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...

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

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

  10. 大话设计模式Python实现- 享元模式

    享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: #!/usr/bin/env python # -*- coding:utf- ...

随机推荐

  1. Java单例模式深入详解

    原文地址:http://www.cnblogs.com/hxsyl/ 仅作为笔记收藏…… 一.问题引入 偶然想想到的如果把Java的构造方法弄成private,那里面的成员属性是不是只有通过stati ...

  2. [转]显示文件命令:cat、more、less、tail、touch详解

    cat命令cat命令连接文件并打印到标准输出设备上.cat经常用来显示文件的内容,类似于下的type命令. 一般格式:cat [选项] 文件说明:该命令有两项功能,其一是用来显示文件的内容,它依次读取 ...

  3. 《React-Native系列》38、 ReactNative混合组件封装

    在我们做ReactNative项目的过程中,我们会发现由ReactNative提供给我们的组件或API往往满足不了我们的需求,常常需要我们自己去封装Native组件. 今天我们介绍下如果封装一个简单的 ...

  4. Eyeshot Ultimate 学习笔记(1)

    在Winform项目中用到3D技术,这是在做项目一段时间以来第一次,还是指定的3D控件Eyeshot Ultimate,这个控件名称用度娘搜索,竟然毫无结果,不知道是没有人用过还是觉得该控件过于简单, ...

  5. mac+eclipse+svn+maven经验总结(转)

    1.Eclipse for Mac:http://mirrors.ustc.edu.cn/eclipse/technology/epp/downloads/release/indigo/SR2/ecl ...

  6. 很少有人知道的c++中的try块函数

    c++有一些在现实世界中很少看到的结构.这些结构有着自己的用法,但是要特别小心保守的予以运用.就像是网站 The Old New Thing首页标题上面的说的那样: “代码通常被读的次数原因超过了被写 ...

  7. python第一次上机遇到的困难

      正确 10 58 27412 2-1019 长度转换程序(10分) 完善下面的程序,能够: (1) 将用户输入的公制长度单位(米.千米)转换成英制长度单位(英寸.英里): (2) 将用户输入的英制 ...

  8. win7下配置IIS服务器方法

    网站爱好初学者必看的win7系统配置自己的IIS,可以在你自己的电脑上配置网站服务器发不到网上,下面就跟着我的步骤一起做吧100%成功. 步骤方法 1.点击开始-------控制面板这个就是打开的控制 ...

  9. gcc/g++编译

    1. gcc/g++在执行编译工作的时候,总共需要4步 (1).预处理,生成.i的文件[预处理器cpp] (2).汇编,将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs] (3).编译,将 ...

  10. python获取本地ip地址的方法

    #_*_coding:utf8_*_ #以下两种方法可以在ubuntu下或者windows下获得本地的IP地址 import socket # 方法一 localIP = socket.gethost ...