本文源码:GitHub·点这里 || GitEE·点这里

一、使用场景

应用代码

public class C01_InScene {
public static void main(String[] args) {
String c0 = "cicada" ;
String c1 = "cicada" ;
System.out.println(c0 == c1); // true
}
}

String类型就是使用享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝,其中c0和c1就是一个字符串常量。结果为:true,说明c0和c1两个引用都指向了常量池中的同一个字符串常量"cicada"。这样的设计避免了在创建N多相同对象时所产生的不必要的大量的资源消耗。

二、享元模式

1、基础简介

享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有需要的则直接拿来用,避免重新创建。

2、模式图解

3、核心角色

  • 抽象享元角色

给出一个抽象接口,以规定具体享元角色要实现的方法。

  • 具体享元角色

实现抽象享元角色所规定出的接口。如果有内部状态的话,必须为内部状态提供存储能力。

  • 享元工厂角色

负责创建和管理享元角色。必须保证享元对象可以被系统选择性共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经存在,直接返回该对象;如果系统中没有该享元对象,享元工厂角色就应当创建该享元对象。

4、内部外部状态

  • 内部状态指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变。
  • 外部状态指对象得以依赖的一个标记,可以随环境改变而改变的、不可共享的状态。

5、源码实现

public class C02_FlyWeight {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly = factory.factoryMethod('c');
fly.printState("One");
fly = factory.factoryMethod('d');
fly.printState("Two");
fly = factory.factoryMethod('c');
fly.printState("San");
// 调用了三次工厂方法,只创建了两个对象
factory.poolInfo();
}
}
/**
* 抽象享元角色类
*/
interface Flyweight {
void printState (String state);
}
/**
* 具体享元角色类
*/
class ConcreteFlyweight implements Flyweight {
private Character innerState = null;
public ConcreteFlyweight (Character state){
this.innerState = state;
}
@Override
public void printState(String state) {
System.out.println("内部状态:" + this.innerState);
System.out.println("外部状态:" + state);
}
}
/**
* 享元工厂角色类
*/
class FlyweightFactory {
// 模拟数据池
private Map<Character,Flyweight> pool = new HashMap<>();
public Flyweight factoryMethod (Character state){
//先从缓存中查找对象
Flyweight fly = pool.get(state);
if(fly == null){
fly = new ConcreteFlyweight(state);
pool.put(state, fly);
}
return fly;
}
public void poolInfo (){
System.out.println("数据池:"+pool);
}
}

三、JDK应用场景

  • 测试代码块
public class C03_Integer {
public static void main(String[] args) {
Integer c1 = Integer.valueOf(127),c2 = Integer.valueOf(127) ;
Integer c3 = new Integer(127),c4 = new Integer(127) ;
boolean flag1 = c1==c2 ,flag2 = c2==c3,flag3 = c3==c4 ;
// true;false;false
System.out.println(flag1+";"+flag2+";"+flag3);
Integer c5 = Integer.valueOf(222),c6=Integer.valueOf(222) ;
// false
System.out.println(c5==c6);
}
}
  • 源码分析
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

这里valueOf方法的意思就是,如果传入的数据在 (-128) 到 (127) 之间,则从缓存中直接返回,否则创建一个新的Integer对象。

四、模式总结

享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时。不需一直创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率。经典的应用场景就是池技术,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,享元模式是池技术的重要实现方式。享元模式使得系统更加复杂。为了使对象可以共享,需要时刻管理对象的状态变化,这使得程序的逻辑变得复杂。

五、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

Java描述设计模式(18):享元模式的更多相关文章

  1. JavaScript设计模式-18.享元模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. python设计模式之享元模式

    python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...

  3. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  4. JAVA设计模式之享元模式

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

  5. Java进阶篇设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  6. Java设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  7. 11.java设计模式之享元模式

    基本需求: 小型的外包项目,给客户A做一个产品展示网站,客户A的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同 每个客户要求发布的方式不一样,A要求以新闻的方式发布,B要求以博客的方 ...

  8. Java设计模式15:常用设计模式之享元模式(结构型模式)

    1. Java之享元模式(Flyweight Pattern) (1)概述:       享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...

  9. 由奶茶店突发奇想开始了Java设计模式:享元模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 奶茶摊位的例子 奶茶店的例子 在什么情况下使用享元模式 定义 享元模式是对象的结构模式,享元模式以共享的方式高效的支持大量的细粒度对象,主要用于 ...

随机推荐

  1. 做高逼格程序员之说走就走的「Windows」

    简介:随着移动固态硬盘越来越便宜,网上逐渐出来一个黑科技.Windows To GO见名知意.简单来说就是在U盘或者是移动固态硬盘上安装Windows系统.达到即插即用. WTG 简介 Windows ...

  2. C++学习笔记-预备知识

    1.1 C++简介 C++融合3种不同的编程方式:C语言代表的过程性语言.C++在C语言基础上添加的类代表的面向对象语言.C++模板支持的广泛编程. 1.2 C++简史 1.2.1 C语言 Ritch ...

  3. 不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤

    数据库查询相信很多人都不陌生,所有经常有人调侃程序员就是CRUD专员,这所谓的CRUD指的就是数据库的增删改查. 在数据库的增删改查操作中,使用最频繁的就是查询操作.而在所有查询操作中,统计数量操作更 ...

  4. 微信小程序前端页面书写

    微信小程序前端页面书写 WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. 一.数据绑定 1. 普通写法 <view ...

  5. postman常用断言

    1.Code is 200 断言状态码是200 2.contains string 断言respoonse body中包含string 3.json value check (检查JSON值)

  6. Bran的内核开发教程(bkerndev)-05 打印到屏幕

    打印到屏幕   现在, 我们需要尝试打印到屏幕上.为此, 我们需要管理屏幕滚动, 如果能允许使用不同的颜色就更好了.好在VGA视频卡为我们提供了一片内存空间, 允许同时写入属性字节和字符字节对, 可以 ...

  7. 渗透测试-基于白名单执行payload--Csc

    复现亮神课程 基于白名单执行payload--csc 0x01 Csc.exe C#的在Windows平台下的编译器名称是Csc.exe,如果你的.NET FrameWork SDK安装在C盘,那么你 ...

  8. 利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图

    作为一名linux系统下的C语言开发,日常工作中经常遇到两个问题: 一是分析代码过程中,各种数据结构互相关联,只通过代码很难理清系统中所有结构体的整体架构,影响代码消化的效率; 二是多层头文件嵌套包含 ...

  9. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266烧录配置

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  10. idea的tomcat实现热部署遇到的问题

    选择Deployment的时候,要选择exploded结尾的,否则不支持热部署