享元模式适用于需要大量相同类型对象的情况。在此,设计布局可以减少创建多个对象的方式。对象在运行时会消耗资源,因此最好在内存中使用较少的对象。它减少了内存占用并利用了程序的整体性能。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。通过Java中的一个简单示例深入研究了这种模式。

深入探索Java设计模式(一)之单例模式

深入探索Java设计模式(二)之策略模式

深入探索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设计模式(四)之享元模式的更多相关文章

  1. Java设计模式之《享元模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6542449.html 享元模式:"享"就是分享之意,指一物被众人共享, ...

  2. 重学 Java 设计模式:实战享元模式「基于Redis秒杀,提供活动与库存信息查询场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 程序员‍‍的上下文是什么? 很多时候一大部分编程开发的人员都只是关注于功能的实现,只 ...

  3. Java设计模式学习记录-享元模式

    前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...

  4. 【转】Java设计模式之《享元模式》及应用场景

    享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的终旨所在. 享元模式有点类似于单例模式,都是只生成一个对象来被共享使用.这里有个问题,那就是对共享对象的修改,为了避免出现这种情况,我 ...

  5. java设计模式-----10、享元模式

    Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用.它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使 ...

  6. Java设计模式:Flyweight(享元)模式

    概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...

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

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

  8. Java描述设计模式(18):享元模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.使用场景 应用代码 public class C01_InScene { public static void main(String[] ...

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

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

  10. 设计模式学习之享元模式(Flyweight,结构型模式)(20)

    转:http://terrylee.cnblogs.com/archive/2006/03/29/361767.html 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是 ...

随机推荐

  1. ZeroC ICE的远程调用框架 AMD

    继上一篇<ZeroC ICE的远程调用框架>,本篇再来说其中的AMD.(本篇需要重写) 当在ice文件中声明某个接口方法Method为["amd"]后,接口方法在stu ...

  2. 关闭zabbix 告警

    1. 到触发器配置界面开启Allow manual close. (可能需要在连接的模板处修改) 2. 永久关闭告警,即disable该触发器.

  3. 【Linux系列】Centos 7安装 PHP(四)

    目的 为了下面的Laravel部署,本篇开始安装PHP. 设置PHP源 查看Centos源是否有PHP. yum list php* 进一步查看PHP的版本. yum info php.x86_64 ...

  4. 教你用Java web实现多条件过滤功能

    生活中,当你闲暇之余浏览资讯的时候,当你搜索资料但繁杂信息夹杂时候,你就会想,如何更为准确的定位需求信息.今天就为你带来: 分页查询 需求分析:在列表页面中,显示指定条数的数据,通过翻页按钮完成首页/ ...

  5. day 17 re模块 正则表达式

    import re    引用re模块 查找 finall:匹配所有,每一项都是列表中的一个元素 search:只匹配从左到右的第一个,得到的不是直接的结果而是一个变量,通过group方法获取结果,没 ...

  6. Chrom谷歌浏览器没网之最全解决办法之一

    一开始查找百度很多方法都不行,,第一次尝试.最有希望和看着像的是:1.win+r --> 输入regedit 打开注册表2.打开目录HKEY_CURRENT_USER\Software\Micr ...

  7. day20191010ClassNotes

    笔记: 1.DAO模式组成部分: 程序 ----> 数据库 实体类 数据库中的表 工具类:公共的数据库连接.关闭.公共的增删改.查询 接口 : 程序提倡的是面向接口编程,从而降低程序的耦合性 实 ...

  8. php踩过的那些坑(5)浮点数计算

    一.前方有坑 php在使用加减乘除等运算符计算浮点数的时候,经常会出现意想不到的结果,特别是关于财务数据方面的计算,给不少工程师惹了很多的麻烦.比如今天工作终于到的一个案例: $a = 2586; $ ...

  9. js对象可扩展性和属性的四个特性(上)

    # js对象可扩展性和属性的四个特性(上) 一.前言 再次花时间回顾一下基础,毕竟要想楼建的好,地基就要牢固,嘻嘻! 在开始之前需要具备对prototype.__proto__.constructor ...

  10. ThinkPHP5——模型(model)的使用

    在使用ThinkPHP5的过程中,我经常使用db进行数据库操作的,后来接触到了模型(model),刚使用时感觉跟db没啥区别,后来查官网知道模型基类中还提供了较多的其他的方法可以方便使用例如获取器.修 ...