别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

    • Python 设计模式
    • 装饰器模式
    • 抽象工厂模式
    • 建造者模式/生成器模式
    • 原型模式
    • 单例模式
    • 设计模式(2)——工厂方法模式
    • 设计模式(3)——抽象工厂模式
    • 设计模式(4)——模板方法模式
    • 设计模式(5)——代理模式
    • 设计模式(6)——建造者模式
    • 设计模式(7)——策略模式
    • 设计模式(8)——命令模式
    • 设计模式(9)——原型模式
    • 设计模式(10)——中介者模式
    • 设计模式(11)——责任链模式
    • 设计模式(12)——装饰器模式
    • 设计模式(13)——适配器模式
    • 设计模式(14)——迭代器模式
    • 设计模式(15)——观察者模式
    • 设计模式(16)——外观模式
    • 设计模式(17)——状态模式
    • 设计模式(18)——桥接模式
    • 设计模式(19)——享元模式
      • 基本思想和原则
      • 动机
      • 实现
      • 优点
      • 缺点
    • 设计模式(20)——解释器模式
    • 设计模式(21)——组合模式
    • 设计模式(23)——备忘录模式
    • Python 全栈之路系列之单例设计模式
    • 设计模式(22)——访问者模式
    • 工厂方法模式
    • Python 设计模式资源收集
  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 设计模式
佚名
2017-12-20
目录

设计模式(19)——享元模式

本文介绍享元模式的概念和应用。

# 基本思想和原则

使用共享对象可有效地支持大量的细粒度的对象。

# 动机

当系统中有大量相似对象存在,它们具有一定的共性,但又有自己特殊的地方,我们可以利用享元模式将这些共性提炼成对象的外部特征,预先创建出这些对象,之后需要时可以直接取出使用,然后再赋予其非共性的属性。

# 实现

数据库连接池就是一个典型的享元模式的应用,预先创建一些数据库连接,当需要时直接取用,而不是立刻创建一个,这种池技术可以有效降低系统开销。

public class DBConnection {
    private int id;

    public DBConnection(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }
}

public class DBConnectionFactory {
    private static Vector<DBConnection> pool = new Vector<DBConnection>();
    private static Vector<Integer> connectionStates = new Vector<Integer>();

    public static void init(int n) {
        for(int i = 0; i < n; i++) {
            DBConnection conn = new DBConnection(i);
            pool.add(conn);
            connectionStates.add(0);
        }
    }

    public static DBConnection getDBConnection() {
        for(int i = 0; i < pool.size(); i++) {
            if (connectionStates.get(i).equals(0)) {
                connectionStates.set(i, 1);
                return pool.get(i);
            }
        }
        return null;
    }

    public static void releaseDBConnection(DBConnection conn) {
        int index = pool.indexOf(conn);
        connectionStates.set(index, 0);
    }
}

public class DBClientThread extends Thread {
    private DBConnection conn;
    public DBClientThread(DBConnection conn) {
        this.conn = conn;
    }
    public void run() {
        System.out.println("Use DBConnection id: " + this.conn.getId());
        try {
            Thread.sleep(250);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        DBConnectionFactory.releaseDBConnection(this.conn);
        this.conn = null;
    }
}

public class Test {
    public static void main(String[] args) {
        DBConnectionFactory.init(5);

        for (int i = 0; i < 10; i++) {
            DBConnection conn = DBConnectionFactory.getDBConnection();
            if (conn != null) {
                DBClientThread thread = new DBClientThread(conn);
                thread.start();
            } else {
                System.out.println("Can not get a db conn.");
            }

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

输出如下:

Use DBConnection id: 0
Use DBConnection id: 1
Use DBConnection id: 2
Use DBConnection id: 3
Use DBConnection id: 4
Use DBConnection id: 0
Use DBConnection id: 1
Use DBConnection id: 2
Use DBConnection id: 3
Use DBConnection id: 4
1
2
3
4
5
6
7
8
9
10

上面的代码模拟了数据库连接池的使用,我们预先创建 5 个数据库连接,然后创建出 10 个线程去获取这个连接。当要获取连接时,不是去实时地创建连接,而是从连接池中获取,使用完连接后还要将连接放回池中(其实就是改变连接的状态)。这几个连接对象被共享出来,供各个线程获取。这是享元模式的一种很重要的应用。

# 优点

享元模式预先创建出一些对象,然后缓存这些对象,当需要时直接取出使用。可以帮助系统减少对象的创建,降低内存占用,提高系统性能。

# 缺点

享元模式会使系统的复杂度提高,我们需要维护这些对象的创建和存在。而且如果系统不需要对象时,这些预先创建的对象还会存在,也是占用内存的,不过这个一般不会成为太大问题。

编辑 (opens new window)
#设计模式
上次更新: 2024-07-23, 01:00:43
设计模式(18)——桥接模式
设计模式(20)——解释器模式

← 设计模式(18)——桥接模式 设计模式(20)——解释器模式→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式