Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • JavaSE

  • JavaEE

  • Linux

  • MySQL

  • NoSQL

  • Python

  • Python模块

  • 机器学习

  • 设计模式

    • 设计模式的概念
    • 创建型模式
    • 单例(Singleton)模式
    • 原型(Prototype)模式
    • 工厂(Factory)模式
    • 建造者(Builder)模式
    • 结构型模式(Structural Pattern)
    • 适配器模式(Adapter Pattern)
    • 桥接模式(Bridge Pattern)
    • 装饰器模式(Decorator、Wrapper(包装) Pattern)
    • 代理模式(Proxy Pattern)
    • 外观模式(Facade Pattern)
    • 组合模式(Composite Pattern)
    • 享元模式(Flyweight Pattern)
      • 应用场景
      • 注意事项和细节
    • 行为型模式(Behavioral Patterns)
    • 模板方法(Template Method)
    • 策略(Strategy)模式
    • 状态(State)模式
    • 中介者(Mediator)模式
    • 观察者(Observer)模式
    • 备忘录(Memento)模式
    • 解释器(Interpreter)模式
    • 命令(Command)模式
    • 迭代器(Iterator)模式
    • 访问者(Visitor)模式
    • 职责链(Chain of Responsibility)模式
    • 总结
  • 传智健康

  • 畅购商城

  • 博客项目

  • JVM

  • JUC

  • Golang

  • Kubernetes

  • 硅谷课堂

  • C

  • 源码

  • 神领物流

  • RocketMQ

  • 短链平台

  • 后端
  • 设计模式
Iekr
2023-12-09
目录

享元模式(Flyweight Pattern)

# 享元模式(Flyweight Pattern)

  • 享元模式 (Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。对象结构型
  • 在享元模式中可以共享的相同内容称为内部状态 (IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态 (Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
  • 在享元模式中通常会出现工厂模式,需要创建 ** 一个享元工厂来负责维护一个享元池 (Flyweight Pool)** 用于存储具有相同内部状态的享元对象。

image-20231209192227686

Flyweight: 抽象享元类 Connection

@Data
public abstract class AbstractWaitressFlyweight {

    boolean canService = true; // 是否能服务
    // 正在服务。。。 享元的不可共享属性留给外部进行改变的接口
    abstract void service();

    // 服务完成。。。 享元的不可共享属性留给外部进行改变的接口
    abstract void end();
}
1
2
3
4
5
6
7
8
9
10

ConcreteFlyweight: 具体享元类 ConnectionImpl(user,pwd,url)

@AllArgsConstructor
public class BeautifulWaitress extends AbstractWaitressFlyweight {
    String id; // 工号
    String name; // 名字
    int age;// 年龄
    // 以上都是不变的属性



    @Override
    void service() {
        System.out.println("工号:" + id + ";" + name + " " + age + "正在服务...");
        // 改变外部的状态
        canService = false;
    }

    @Override
    void end() {
        System.out.println("工号:" + id + ";" + name + " " + age + "服务结束...");
        // 改变外部的状态
        canService = true;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

FlyweightFactory: 享元工厂类;简单工厂,产品就一个 Connection

public class ZuDao {
    private static Map<String, AbstractWaitressFlyweight> pool = new HashMap<>();

    // 享元,池子中有对象
    static {
        BeautifulWaitress waitress = new BeautifulWaitress("1234", "小芳", 18);
        BeautifulWaitress waitress2 = new BeautifulWaitress("9527", "小梅", 19);

        pool.put(waitress.id, waitress);
        pool.put(waitress2.id, waitress2);
    }

    public void addWaitress(AbstractWaitressFlyweight waitressFlyweight) {
        pool.put(UUID.randomUUID().toString(), waitressFlyweight);
    }

    public static AbstractWaitressFlyweight getWaitress(String name) {
        AbstractWaitressFlyweight flyweight = pool.get(name);
        if (flyweight == null) {
            Collection<AbstractWaitressFlyweight> values = pool.values();
            for (AbstractWaitressFlyweight value : values) {
                // 当前共享对象是否能进行服务
                if (value.isCanService()) {
                    return value;
                }
            }
            return null;
        }

        return flyweight;

    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

测试

public class MainTest {
    public static void main(String[] args) {
        AbstractWaitressFlyweight waitress = ZuDao.getWaitress("");
        waitress.service();
        System.out.println(waitress);

        AbstractWaitressFlyweight waitress1 = ZuDao.getWaitress("");
        waitress1.service();
        System.out.println(waitress1);

        AbstractWaitressFlyweight waitress2 = ZuDao.getWaitress("");
        // 没有可用服务元 返回null
        System.out.println(waitress2);

        // 有一个服务员结束服务 再进行获取服务员
        waitress1.end();
        waitress2 = ZuDao.getWaitress("");
        System.out.println(waitress2);


    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 应用场景

什么场景用到?

  • 典型的代表:数据库连接池
  • 所有的池化技术
  • 享元和原型模式有什么区别?享元是预先准备好的对象进行复用,原型没法确定预先有哪些

Integer 中的享元模式

image-20231209194810631

public static void main(String[] args) {
    // TODOAuto-generated method stub
    //如果 Integer.valueOf(x) x 在 -128 --- 127 直接,就是使用享元模式返回,如果不在
    //范围类,则仍然 new
    //小结:   
    //1. 在 valueOf 方法中,先判断值是否在 IntegerCache 中,如果不在,就创建新的 Integer(new), 否则,就
    直接从 缓存池返回
    //2. valueOf 方法,就使用到享元模式
    //3. 如果使用 valueOf 方法得到一个 Integer 实例,范围在 -128 - 127 ,执行速度比 new 快
    Integer x = Integer.valueOf(127); // 得到 x 实例,类型 Integer
    Integer y = new Integer(127); // 得到 y 实例,类型 Integer
    Integer z = Integer.valueOf(127);//..
    Integer w = new Integer(127);
    System.out.println(x.equals(y)); // 大小,true
    System.out.println(x == y ); // false
    System.out.println(x == z ); // true
    System.out.println(w == x ); // false
    System.out.println(w == y ); // false
    Integer x1 = Integer.valueOf(200);
    Integer x2 = Integer.valueOf(200);
    System.out.println("x1==x2" + (x1 == x2)); // false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 注意事项和细节

  1. 在享元模式这样理解,“享” 就表示共享,“元” 表示对象
  2. 系统中有大量对象,这些对象消耗大量内存,并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式
  3. 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用 HashMap/HashTable 存储
  4. 享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率
  5. 享元模式提高了 系统的复杂度。需要分离出 内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变,这是我们使用享元模式需要注意的地方.
  6. 使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。
  7. 享元模式经典的应用场景是需要缓冲池的场景,比如 String 常量池、数据库连接池
编辑 (opens new window)
上次更新: 2023/12/13, 06:06:02
组合模式(Composite Pattern)
行为型模式(Behavioral Patterns)

← 组合模式(Composite Pattern) 行为型模式(Behavioral Patterns)→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式