模式简介

Flyweight是轻量的意思,此模式将要用的对象放到“对象池”中,随取随用,不重复创建对象,达到减少对象内存占用的目的,实现了对象的“轻量”。

在数据库连接池、字符串缓存池里面都有此模式的应用。

此模式的中文表述为:享元模式

示例代码

代码功能与实现思路

输入一个数字字符串,比如“121”,以"大型字符"形式输出出来。

输出的“大型字符”如下所示:

......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................

一个“大型字符”就是一个很长的字符串,就是“重量级对象”,如果输入一串数字比如“1654843987461935”,把每一个数字对应的“大型字符”都创建成对象,内存占用会很可观。

观察可知,数字串里只包含0到9共十个数字,因此可以将数字对应的“大型字符”存到一个“对象池”里,每个对象只保存一份,用的时候取出来即可。这样可以大大减少内存占用。

类图

代码

BigChar:表示一个数字对应的“大型字符”,charname是数字字符,fontdata是存储“大型字符”的字符串。

构造函数从文件里面读取“大型字符”的字符串数据保存到fontdata里面。

public class BigChar {
// 字符名字
private char charname;
// 大型字符对应的字符串(由'#' '.' '\n'组成)
private String fontdata;
// 构造函数
public BigChar(char charname) {
this.charname = charname;
try {
//从文件里面读取
BufferedReader reader = new BufferedReader(
new FileReader("D:\\" + charname + ".txt")
);
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("\n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?";
}
}
// 显示大型字符
public void print() {
System.out.print(fontdata);
}
}

BigCharFactory:“大型字符”的工厂,pool就是对象池。使用了单例模式,整个程序里面只有一个工厂,工厂里面有一个对象池,需要“大型字符”就到对象池里面取,如果对象池里面有对应的“大型字符”则直接给予,没有就创建一个再给。

public class BigCharFactory {
// 管理已经生成的BigChar的实例
private HashMap pool = new HashMap();
// Singleton模式
private static BigCharFactory singleton = new BigCharFactory();
// 构造函数
private BigCharFactory() {
}
// 获取唯一的实例
public static BigCharFactory getInstance() {
return singleton;
}
// 生成(共享)BigChar类的实例
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname); // 生成BigChar的实例
pool.put("" + charname, bc);
}
return bc;
}
}

BigString:将数字字符串以“大型字符”形式输出。

public class BigString {
// “大型字符”的数组
private BigChar[] bigchars;
// 构造函数
public BigString(String string) {
bigchars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
}
// 显示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
bigchars[i].print();
}
}
}

Main

public class Main {
public static void main(String[] args) {
BigString bs = new BigString("1212123");
bs.print();
}
}

结果图示分析

模式角色和类图

角色

  • Flyweight

Flyweight表示那些实例会被共享的类。在本例中,由BigChar扮演此角色。

  • FlyweightFactory

FlyweightFactory角色是生成Flyweight角色的工厂。在工厂中生成Flyweight角色可以实现实例共享。在本例中,由BigCharFactory类扮演此角色。

  • Client

Client角色使用FlyweightFactory类的单例实例生成Flyweight角色并使用之。在本例中,由BigString类扮演此角色。

类图

拓展思路

对多个地方产生影响

共享对象,意味着一旦对象发生改变,所有引用它的地方都要变,注意这个特点,修改之前要考虑好造成的影响。

什么要共享,什么不要共享

应当共享的信息被称为Intrinsic,表示本质的,固有的。即不依赖于实例状态,无论在什么情况下都不会改变的信息,可以被共享。

不应当共享的信息被称为Extrinsic,表示外在的,非本质的。即随时可能变化的信息,不应该被共享。

垃圾回收

如果对象占用了过多内存,JVM就要开始回收垃圾了。如果一个对象没有被任何实例引用,垃圾回收器就会认为这是个垃圾,会回收掉。在上面例子中,由于pool是HashMap,里面的共享对象始终会被pool引用,所以不会被回收。

《图解设计模式》读书笔记9-1 Flyweight模式的更多相关文章

  1. HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)

    装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...

  2. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  3. Head First 设计模式读书笔记(1)-策略模式

    一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...

  4. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...

  5. 图解http读书笔记

    以前对HTTP协议一知半解,一直不清楚前端需要对于HTTP了解到什么程度,知道接触的东西多了,对于性能优化.服务端的配合和学习中也渐渐了解到了HTTP基础的重要性,看了一些大神对HTTP书籍的推荐,也 ...

  6. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

  7. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  8. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  9. C#设计模式学习笔记:(23)解释器模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...

  10. 设计模式(二十)Flyweight模式

    当使用new关键字生成类的实例时,需要给其分配足够的内存空间.当程序中需要大量对象时,如果都是用new关键字来分配内存,将会消耗大量内存空间.Flyweight模式就是尽量避免new出实例,而是通过尽 ...

随机推荐

  1. k3 cloud中单据体中文本自适应

    在单据体中添加多行文本,然后设置本地配置,只读单元格自动换行

  2. Redis数据结构&命令手册

    Redis数据结构&命令手册 Redis数据结构 Redis可以存储键与5种不同数据结构之间的映射,这五种数据结构类型分别为STRING(字符串).LIST(列表).SET(集合).HASH( ...

  3. Java web项目搭建系列之二 Jetty下运行项目

    在项目pom.xml文件中添加Jetty运行配置 在pom.xml文件project节点下插入如下代码: <build> <plugins> <plugin> &l ...

  4. 011-linux服务管理

    linux服务管理 [root@zabbix lianxi]# chkconfig --list 注:该输出结果只显示 SysV 服务,并不包含 原生 systemd 服务.SysV 配置数据 可能被 ...

  5. Comet OJ - Contest #2 B 她的想法、他的战斗(概率 + 数学)

    题目描述 Takuru 是一名情报强者,所以他想利用他强大的情报搜集能力来当中间商赚差价. Takuru 的计划是让 Hinae 帮他去市场上买一个商品,然后再以另一个价格卖掉它.Takuru 会给 ...

  6. c语言之ascii字符

    int main(){ char buf[20] = {104,101,108,108,111,0}; printf("buf:%s\n",buf); return 0;} 打印结 ...

  7. pyhive

    from pyhive import hiveimport pandas as pdimport numpy as npclass myhive():    def __init__(self,hos ...

  8. 【UOJ#400】暴力写挂

    题目链接 题意 两棵树 , 求出下面式子的最大值. \[dep[u]+dep[v]-dep[LCA(u,v)]-dep'[LCA'(u,v)]\] Sol 边分治. 与第一棵树有关的信息比较多,所以对 ...

  9. POJ-3436-ACM Computer Factory(最大流, 输出路径)

    链接: https://vjudge.net/problem/POJ-3436#author=0 题意: 为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产 ...

  10. 对postcss以及less和sass的研究

    1.postcss PostCSS 的主要功能只有两个:第一个就是前面提到的把 CSS 解析成 JavaScript 可以操作的 抽象语法树结构(Abstract Syntax Tree,AST),第 ...