模式简介

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. C#.NET、Power BI、数据挖掘

    阅读目录 1.采集目目标特点与分析 2.方案第一版-Low到爆,别笑话 3.碰壁后的第二版方案 4.最终方案第三版 5.总结 说起采集,其实我是个外行,以前拔过阿里巴巴的客户数据,在我博客的文章:C# ...

  2. C++设计模式:访客模式

    访客模式:通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问. 访客模式的侵入性适中,仅在被访问的类里面加一个对外提供接待访问者的接口. 访客模式的优点: 符合单一职责原 ...

  3. #define 宏实现函数功能可能存在的问题

    #define 宏实现函数功能的问题 情形1 #define free_ptr(p) \ if(p) delete p; p = nullptr; 在调用free_ptr(p)的地方展开看这段代码: ...

  4. SpringBoot自定义配置步骤

    1. 在yml中填写自定义配置 ly: sms: accessKeyId: # 短信配置 accessKeySecret: signName: xx商城 # 签名名称 verifyCodeTempla ...

  5. 基于ELK进行邮箱访问日志的分析

    公司希望能够搭建自己的日志分析系统.现在基于ELK的技术分析日志的公司越来越多,在此也记录一下我利用ELK搭建的日志分析系统. 系统搭建 系统主要是基于elasticsearch+logstash+f ...

  6. vue filters过滤

    <template> <div class="filters"> <h1 v-text="filtersTitle">< ...

  7. KFK2060穿越者

  8. MySQL使用explain时各字段解释

    1.id select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序 三种情况: (1)id相同,执行顺序由上至下 id相同,执行顺序由上至下 此例中 先执行where 后的 ...

  9. C# wpf 列出文件夹所有文件

    在网上找了 cmd输入 dir "要列出的文件夹*.*" /a /b /s>"要输出的文件" 可以重定向把文件夹内容输出到文件 tree "要列 ...

  10. Utorrent死机恢复种子下载

    死机保存Utorrent种子不被删除方法: 保了200多个种,死机了重启就没有什么下载的种子的记录,要一个个导入实在奔溃. 从被删除的resume.dat恢复很有压力. 简单的方法: 在还没有死机前, ...