深入探索Java设计模式(四)之享元模式
享元模式适用于需要大量相同类型对象的情况。在此,设计布局可以减少创建多个对象的方式。对象在运行时会消耗资源,因此最好在内存中使用较少的对象。它减少了内存占用并利用了程序的整体性能。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。通过Java中的一个简单示例深入研究了这种模式。
总览
轻量级模式减少了重复数据的使用。通常的做法是将对象设计成细粒度以利用其使用的灵活性。但是,问题是对象在运行时会消耗资源。粒度会不利地影响应用程序的性能,因为需要将运行时对象容纳在更大的内存集中。每个对象不仅消耗内存,而且消耗CPU周期。在这种情况下,轻量化模式可以通过减少细粒度对象的重复实例化来解决。
享元模式Flyweight Pattern
享元模式分为两部分:
- 内部的:这是独立的部分,数据存储在对象中,与享元模式上下文无关。结果,它对于所有相同的固有数据都是可共享的,因此可以用享元模式对象替换。
- 外在的: 这是从属部分,其中保留了举重对象的上下文信息。这是不可共享的。状态由客户端对象存储,并根据要求传递给享元模式对象。
享元模式的使用
在我们有许多表示相同值的对象的情况下,这很有用。因此,它使不可变对象的值可共享。例如,在下面的代码片段中观察Java标准库的Integer包装器类的valueOf()方法如何检查给定参数的值。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
如果该值先前已缓存,则该方法将返回构造函数实例,而不是创建一个新对象。因为缓存是在静态块中初始化的,所以仅在第一次调用时才创建Integer实例。请注意,IntegerCache类是在Integerclass中定义的私有静态类。
private static class IntegerCache {
// ...
static {
// ...
cache = new Integer[(high - low) + 1];
int j = low;
for (int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// Range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
// ...
}
现在,我们可以测试Integer类是否创建两个不同的对象(如果值相同)。将图1中的输出与以下代码进行比较。
public class JustForTesting {
public static void main(String[] args){
final Integer intObj1 = Integer.valueOf(10);
final Integer intObj2 = Integer.valueOf(10);
System.out.println("First Case");
if (intObj1 == intObj2){
System.out.println("If the values are same " +
"then the objects are also same.");
} else {
System.out.println("If the values are different " +
"then the objects are also distinct.");
}
// Now, if we change the same value to a different
// value, it becomes two distinct objects final Integer intObj3 = Integer.valueOf(10);
final Integer intObj4 = Integer.valueOf(20);
System.out.println("Second Case");
if (intObj3 == intObj4){
System.out.println("If the values are same " +
"then the objects are also same.");
} else {
System.out.println("If the values are different " +
"then the objects are also distinct.");
}
}
}
输出
图1:前面代码的输出
实现享元模式
这是享元模式的简单实现。观察如何限制具有相同值的对象创建新对象,而不是提供池中已经存在的对象的副本。工厂中的对象池充当保留享元模式实例的缓存。
package testpattern;
public class Car {
private String color;
public Car(String color){
this.color = color;
System.out.println("Painted with "+color+" color.");
}
public String getColor() {
return color;
}
}
package testpattern;
import java.util.ArrayList;
import java.util.List;
public class CarFactory {
private List<Car> carpool = new ArrayList<>();
public Car getFlyweightCar(String color) {
for (Car c: carpool) {
if (c.getColor().equals(color)){
System.out.println(color +
" car is already in the pool!");
return c;
}
}
Car car = new Car(color);
carpool.add(car);
return car;
}
}
package testpattern;
public class App {
public static void main(String[] args) {
CarFactory cf = new CarFactory();
cf.getFlyweightCar("RED");
cf.getFlyweightCar("BLUE");
cf.getFlyweightCar("GREEN");
cf.getFlyweightCar("PURPLE");
cf.getFlyweightCar("RED");
cf.getFlyweightCar("BLUE");
cf.getFlyweightCar("BLACK");
}
}
输出
图2:享元模式实现的输出
结论
享元模式是在许多情况下使用的常见模式,有时程序员会在不知不觉中使用它。这种模式说明了我们如何使用许多内存不足的对象。如前所述,我们必须始终尽可能利用不变的Integer类的valueOf方法,因为当我们调用new时,即使缓存包含相同的对象,也会创建一个新实例。正如我们已经讨论过的那样,valueOf方法还可以工作。这是使用享元模式的优势。
感谢阅读!欢迎留言。想更深入探讨学习也欢迎私信我。下篇继续~
深入探索Java设计模式(四)之享元模式的更多相关文章
- Java设计模式之《享元模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6542449.html 享元模式:"享"就是分享之意,指一物被众人共享, ...
- 重学 Java 设计模式:实战享元模式「基于Redis秒杀,提供活动与库存信息查询场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 程序员的上下文是什么? 很多时候一大部分编程开发的人员都只是关注于功能的实现,只 ...
- Java设计模式学习记录-享元模式
前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...
- 【转】Java设计模式之《享元模式》及应用场景
享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的终旨所在. 享元模式有点类似于单例模式,都是只生成一个对象来被共享使用.这里有个问题,那就是对共享对象的修改,为了避免出现这种情况,我 ...
- java设计模式-----10、享元模式
Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用.它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使 ...
- Java设计模式:Flyweight(享元)模式
概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...
- 《JAVA设计模式》之享元模式(Flyweight)
在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是 ...
- Java描述设计模式(18):享元模式
本文源码:GitHub·点这里 || GitEE·点这里 一.使用场景 应用代码 public class C01_InScene { public static void main(String[] ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 设计模式学习之享元模式(Flyweight,结构型模式)(20)
转:http://terrylee.cnblogs.com/archive/2006/03/29/361767.html 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是 ...
随机推荐
- PostGIS 报错为org.postgresql.util.PSQLException:错误: Operation on mixed SRID geometries
说明: 在用Openlayers与Geoserver进行开发,做在线编辑功能时,出现一个问题:每当我新增了一根要素后,再次用wfs的方式进行点击查询时,会报错mixed SRID. 通过研究发现在数据 ...
- 宋宝华:关于ARM Linux原子操作的实现
本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 竞态无所不在 首先我们要理解竞态(ra ...
- 使用python删除指定文件夹及子文件,保留多少
python版本为:2.7 import os,time,shutil,datetime def rmdir(deldir,N): dellist=os.listdir(deldir) deldate ...
- 全排列(STL)
输入一个整数n,输出1~n的全排列(是不是很水) 在此记录stl做法 #include<bits/stdc++.h> using namespace std; ]; int main(){ ...
- linux任务计划cron、chkconfig工具、systemd管理服务、unit和target介绍
第8周第1次课(5月14日) 课程内容: 10.23 linux任务计划cron10.24 chkconfig工具10.25 systemd管理服务10.26 unit介绍10.27 target介绍 ...
- Delphi - 调用SuperDll 持续更新
调用SuperDll 接上一篇Delphi创建Superdll,将生成的SuperDll.dll文件复制到本工程路径下,创建如下代码进行Superdll各个接口的测试. 创建uSuperDll.pas ...
- SQL追踪器的安装和使用
SQL追踪器主要作用快速查出错误SQL语言.此工具能几秒钟追踪出sql 数据库操作,能几分钟内分析任意项目系统数据库表结构,瞬间无刷新测试.调试 php代码 第一步:下载 https://pan.ba ...
- 一图读懂基于鲲鹏处理器的全栈混合云华为云Stack6.5
[摘要] 够料的全栈混合云干货信息,速戳! 近日,在2019华为云城市峰会广州站上,华为云发布基于鲲鹏处理器的全栈混合云解决方案HCS 6.5.x86+鲲鹏,双驱动开启云上新架构;云上+本地,双平台无 ...
- 转:浅谈Spring的PropertyPlaceholderConfigurer
大型项目中,我们往往会对我们的系统的配置信息进行统一管理,一般做法是将配置信息配置与一个cfg.properties的文件中,然后在我们系统初始化的时候,系统自动读取cfg.properties配置文 ...
- 15.Django基础十一之认证系统
一 auth模块 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个 ...