zoukankan      html  css  js  c++  java
  • 设计模式--享元模式

    简介

    享元模式又称轻量级模式,是对线程池的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的独享,以此来降低内存的消耗,属于结构型模式。

    享元模式把一个对象的状态分为内部状态和外部状态, 内部状态是不变的,外部状态是变化的;

    然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

    享元模式UML类图:

    从类图看,享元模式有三个参与角色:

    抽象享元角色(Flyweight):享元对象抽象基类或者接口,同时定义出对象的内部状态和外部状态的接口或实现;

    具体享元角色( ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与环境无关,不能出现会有一个操作改变内部状态,同时修改了外部状态;

    享元工厂(FlyweightFactory):负责管理享元对象池和创建享元对象。

    享元模式的应用场景

    当系统中多处需要同一组消息时,可以把这些信息封装到一个对象中,然后对该对象进行缓存,这样,一个对象就可以提供给多处需要使用的地方,避免大量同一对象的多次创建,消耗大量的内存空间。

    享元模式其实就是工厂模式的一个改进机制,享元模式同样要求创建一个或者一组对象,并且就是通过工厂方法生成对象的,只不过享元模式中为工厂内方法增加了缓存这一功能。主要总结为以下应用场景:

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

    2、系统中有大量相似对象、需要缓冲池的场景。

    生活中享元模式的场景

    1、中介机构的房源共享

    2、全国社保联网

    这里的享元模式类似单例模式中的注册式单例模式。但是享元模式的重点是在结构上,而不是在创建对象上。

    享元模式在源码中的应用

    1、String中的享元模式

    ​ java中将String类定义为final(不可改变的),JVM中字符串一般保存在字符串常量池中,java会确保一个字符串在常量池中只有一个拷贝,这个字符串常量池在JDK6.0以前是位于常量池中,位于永久代,而在JDK7.0中,JVM将其从永久代拿出来放置于堆中。

    string中intern()方法能使一个位于堆中的字符串在运行期间动态的加入到字符串常量池中(字符串常量池的内容是程序启动的时候就已经加载好了),如果字符串常量池中有该对象对应的字面量,则返回该字面量在字符串常量池中的引用,否则,创建复制一份该字面量到字符串常量池并返回它的引用。

    2、Integer中的享元模式

    3、Long中的享元模式

    4、Apache Commons Pool2中的享元模式

    享元模式的内部状态和外部状态

    享元模式的定义为我们提出了两个要求:细粒度和共享对象。因为要求细粒度对象,所以不可避免的会使对象数量多且性质相近,此时我们就将这些对象的信息分为两个部分:内部状态和外部状态。

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

    比如,连接池中的连接对象,保存在连接对象中的用户名、密码、连接url等信息,在创建对象的时候就设置好了,不会随环境的改变而改变,这些为内部状态。而每个连接都要回收利用时,我们需要给它标记为可用状态,这些为外部状态。

    享元模式的的优缺点

    优点:

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

    2、减少内存之外的其他资源占用。

    缺点:

    1、关注内、外状态、关注线程安全问题;

    2、是系统、程序的逻辑复杂化。

    代码链接

    享元模式

  • 相关阅读:
    zookeeper历史版本下载
    RabbitMq集群搭建
    spring boot rabbitmq整合rabbitmq之消息持久化存储
    跨域
    Spring注入(IOC):
    AOP
    jsp自定义标签
    配置文件要注意的项
    线程
    URL转码
  • 原文地址:https://www.cnblogs.com/snail-gao/p/15068359.html
Copyright © 2011-2022 走看看