一. 定义与类型

定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象

类型:结构性

二. 使用场景

(1)  常常应用于系统底层的开发,以便解决系统的性能问题

(2)  系统有大量相似对象,需要缓冲池的场景

三. 优缺点

优点:

  (1) 减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率

  (2) 减少内存之外的其他资源占用

缺点:

  (1) 关注内/外状态,关注线程安全问题

  (2) 使系统,程序的逻辑复杂化

四.享元——扩展

内部状态

外部状态

五. 相关设计模式

享元模式和代理模式

  代理模式就是代理一个类,如果生成这个代理类需要花费的资源和时间比较多,就可以使用享元模式,提高系统的速度

享元模式和单例模式

  单例模式中的容器单例就是享元模式的一种使用

六. Coding

以一个业务场景为例,假设每年年底的时候公司中的部门经理都需要写年终报告,但是可能不止要报告一次,需要重复报告。

使用享元模式,可以很好的完成上面的例子。

先创建一个接口:

/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2019-02-12 10:01
**/
public interface Emplyee {
void report();
}

再创建一个经理实体类,来实现接口

/**
* @program: designModel
* @description: 部门manager
* @author: YuKai Fan
* @create: 2019-02-12 10:01
**/
public class Manager implements Emplyee {
public void report() {
System.out.println(reportContent);
}
private String title = "部门经理";
private String department;//部门
private String reportContent;//报告内容 public Manager(String department) {
this.department = department;
} public void setReportContent(String reportContent) {
this.reportContent = reportContent;
}
}

在创建一个员工工厂,通过工厂在获取manager,因为只需要manager做报告,不需要employee。

/**
* @program: designModel
* @description: 员工工厂
* @author: YuKai Fan
* @create: 2019-02-12 10:04
**/
public class EmployeeFactory {
   //因为在享元模式中,一般要考虑线程安全问题,但是还是要看业务场景来使用
private static final Map<String, Emplyee> EMPLYEE_MAP = new HashMap<String, Emplyee>(); public static Emplyee getManager(String department) {
Manager manager = (Manager) EMPLYEE_MAP.get(department);
if (manager == null) {
manager = new Manager(department);
System.out.print("创建部门经理:" + department);
String reportContent = department + "部门汇报:此次报告的主要内容是。。。。";
manager.setReportContent(reportContent);
System.out.println(" 创建报告:" + reportContent);
EMPLYEE_MAP.put(department, manager);
}
return manager;
}
}

应用层:

/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2019-02-12 10:08
**/
public class Test {
private static final String departments[] = {"RD", "QA", "PM", "BD"}; public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String department = departments[(int) (Math.random() * departments.length)];
Manager manager = (Manager) EmployeeFactory.getManager(department);
manager.report();
}
}
}

结果:

UML类图:

从结果可以看出,当部门经理做报告时只需要创建一次即可,下次不需要再次创建。减少了对象的创建

在上面的代码例子中,department相当于外部状态。因为它依赖于外部的传入,为了方便理解,创建一个title属性,它就是一个内部状态,它不随外部状态department的变化而变化。

七. 源码分析

(1)

Integer类就是典型的享元模式的例子

Integer.valueOf中有一个IntegerCache,上面的代码中就对传入的值进行判断。如果是从IntegerCache中取出就直接返回,否则就new一个Integer对象。这也就是如果传入的int值不在固定的范围类,它们做==的时候一定是false,因为不是同一个对象。其中low=-128,high=127.

还有Long类的valueOf,也是同上的道理。

(2)

tomcat中的GenericObjectPoolConfig连接池

java设计模式——享元模式的更多相关文章

  1. 【设计模式】Java设计模式 - 享元模式

    Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  2. JAVA 设计模式 享元模式

    用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象. 享元模式是一种结构型模式. 结构

  3. Java设计模式-享元模式(Flyweight)

    享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查 ...

  4. java设计模式---享元模式

    享元模式 顾名思义:共享元对象.如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用创建新的对象. 享元模式是为数不多的.只为提升系统性能而生的设计模式.它的主要作用就 ...

  5. Java设计模式—享元模式

    享元模式:是池技术的重要实现方式. 定义如下: 使用共享对象可有效地支持大量的细粒度的对象. 个人理解:享元模式利用共享对象的技术,解决了Java中内存溢出的问题. 享元模式的定义为我们提出了两个要求 ...

  6. 8. 星际争霸之php设计模式--享元模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. C++设计模式——享元模式

    本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.如果这篇文章对你有帮助,你可以请我喝杯咖啡. » 本文链接:http:// ...

  8. [工作中的设计模式]享元模式模式FlyWeight

    一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持 ...

  9. 设计模式-享元模式(FlyWeight)

    一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...

随机推荐

  1. Spark为什么比Hadoop好?

    (1)Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk Hadoop每次计算先写磁盘,下次计算先从磁盘读,计算结果再写磁盘,如此往复.这对于迭代计算,是 ...

  2. xshell如何传输文件-yum

    1.安装 sudo yum install  lrzsz -y 2.检查是否安装成功 #rpm -qa |grep lrzsz 出现如下,表示安装成功 3.上传文件的执行命令: #rz 就会打开本地选 ...

  3. python fork函数

    import os print('---父进程id:%s----'%(os.getpid())) pid=os.fork()#只能在liunx环境下执行 print('---%s---' % (os. ...

  4. RTT之shell

    两种shell的切换:如果打开了FINSH_USING_MSH而没有打开FINSH_USING_MSH_ONLY,finsh同时支持两种c-style模式与msh模式,但是默认进入c-style模式, ...

  5. (转)shell中各种括号的作用()、(())、[]、[[]]、{}

    shell中各种括号的作用().(()).[].[[]].{} 原文:http://www.jb51.net/article/60326.htm http://blog.csdn.net/good_h ...

  6. 【input】——数据传入后台

    1.复选框 checkbox <label class="checkbox"> <input type="checkbox" name=&qu ...

  7. 使用Aspose.Cell控件实现Excel高难度报表的生成

    1.使用Aspose.Cell控件实现Excel高难度报表的生成(一) http://www.cnblogs.com/wuhuacong/archive/2011/02/23/1962147.html ...

  8. iOS-swift-函数和闭包

    一.函数 关键字:func 参数列表用 , 分割 使用 -> 分割参数和返回值 func greet(person: String, day: String) -> String { re ...

  9. 在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称

             在契约优先的Web服务开发过程中,往往是先拿到WSDL服务定义,各家开发各自的服务实现或客户端,然后互相调用.          尽管Web Service的标准已经发布很多年,但各 ...

  10. Mysql远程连接授权IP

    新增法   我们现在增加一个'username'用户,密码为'password',让其能够从外部访问MYSQL. grant all on * to 'username' identified by ...