《图解设计模式》读书笔记9-1 Flyweight模式
模式简介
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模式的更多相关文章
- HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- Head First 设计模式读书笔记(1)-策略模式
一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...
- JavaScript设计模式:读书笔记(未完)
该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...
- 图解http读书笔记
以前对HTTP协议一知半解,一直不清楚前端需要对于HTTP了解到什么程度,知道接触的东西多了,对于性能优化.服务端的配合和学习中也渐渐了解到了HTTP基础的重要性,看了一些大神对HTTP书籍的推荐,也 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- C#设计模式学习笔记:(23)解释器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...
- 设计模式(二十)Flyweight模式
当使用new关键字生成类的实例时,需要给其分配足够的内存空间.当程序中需要大量对象时,如果都是用new关键字来分配内存,将会消耗大量内存空间.Flyweight模式就是尽量避免new出实例,而是通过尽 ...
随机推荐
- Linux文档整理之【Nginx安装Docker】
这次整理的文档是Docker安装 先说明下我用的系统是Linux Centos,不同的Linux版本差别不大. 1.安装依赖包 sudo yum install -y yum-utils device ...
- JavaEE高级-MyBatis学习笔记
一.MyBatis简介 - MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架. - MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. - My ...
- 基于TCP/UDP协议的socket
基于TCP协议的socket tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 server端 import socket sk = socket.socket() sk.bind( ...
- [ZJOI2007]最大半连通子图(Tarjan,拓扑序DP)
[ZJOI2007]最大半连通子图 题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v ...
- SSM框架整合之单独整合Mybatis
整合步骤 导入必须jar包 mybatis核心jar包 mybatis依赖jar包 数据库驱动包 建立数据库表 建立实体类 建立Mapper接口 建立sql映射文件 <?xml version= ...
- Java课程作业02
01. 一.设计思想: 第一种使用n!的公式直接计算,利用递归方法求n! 第二种使用递推的公式,利用递归返回求和. 二.程序流程图 三.源代码 import java.util.*;import ja ...
- Windows Server2008R2蓝屏,分析dmp文件
使用Windbp PreView打开dmp文件后,在命令栏输入如下命令: !analyze -v 解析结果中蓝色字体为错误原因分析
- linux C++ 通讯架构(一)nginx安装、目录、进程模型
nginx是C语言开发的,号称并发处理百万级别的TCP连接,稳定,热部署(运行时升级),高度模块化设计,可以用C++开发. 一.安装和目录 1.1 前提 epoll,linux内核版本为2.6或以上 ...
- nyoj 952 : 最大四边形 (计算几何)
题目链接 任意四边形均可看作是两个三角形拼接得到的(即使是凹四边形),故 可以O(n^2)枚举所有的线段,然后对每条线段O(n)枚举线段端点外的其他点,用来更新以此线段构成的三角形的有向面积的最大值m ...
- python之GUI编程-tkinter学习
推荐几个学习网址:https://www.cnblogs.com/shwee/p/9427975.html https://cloud.tencent.com/developer/section/13 ...