设计模式之美:Object Pool(对象池)

 

索引

意图

运用对象池化技术可以显著地提升性能,尤其是当对象的初始化过程代价较大或者频率较高时。

Object pooling can offer a significant performance boost; it is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high.

结构

参与者

Reusable

  • 类的实例与其他对象进行有限时间的交互。

ReusablePool

  • 管理类的实例。

Client

  • 使用类的实例。

适用性

当以下情况成立时可以使用 Object Pool 模式:

  • 类的实例可重用于交互。
  • 类的实例化过程开销较大。
  • 类的实例化的频率较高。
  • 类参与交互的时间周期有限。

效果

  • 节省了创建类的实例的开销。
  • 节省了创建类的实例的时间。
  • 存储空间随着对象的增多而增大。

相关模式

  • 通常,可以使用 Singleton 模式实现 ReusablePool 类。
  • Factory Method 模式封装了对象的创建的过程,但其不负责管理对象。Object Pool 负责管理对象。

实现

实现方式(一):实现 DatabaseConnectionPool 类。

如果 Client 调用 ObjectPool 的 AcquireReusable() 方法来获取 Reusable 对象,当在 ObjectPool 中存在可用的 Reusable 对象时,其将一个 Reusable 从池中移除,然后返回该对象。如果池为空,则 ObjectPool 会创建一个新的 Reusable 对象。

  1 namespace ObjectPoolPattern.Implementation1
2 {
3 public abstract class ObjectPool<T>
4 {
5 private TimeSpan _expirationTime;
6 private Dictionary<T, DateTime> _unlocked;
7 private Dictionary<T, DateTime> _locked;
8 private readonly object _sync = new object();
9
10 public ObjectPool()
11 {
12 _expirationTime = TimeSpan.FromSeconds(30);
13 _locked = new Dictionary<T, DateTime>();
14 _unlocked = new Dictionary<T, DateTime>();
15 }
16
17 public ObjectPool(TimeSpan expirationTime)
18 : this()
19 {
20 _expirationTime = expirationTime;
21 }
22
23 protected abstract T Create();
24
25 public abstract bool Validate(T reusable);
26
27 public abstract void Expire(T reusable);
28
29 public T CheckOut()
30 {
31 lock (_sync)
32 {
33 T reusable = default(T);
34
35 if (_unlocked.Count > 0)
36 {
37 foreach (var item in _unlocked)
38 {
39 if ((DateTime.UtcNow - item.Value) > _expirationTime)
40 {
41 // object has expired
42 _unlocked.Remove(item.Key);
43 Expire(item.Key);
44 }
45 else
46 {
47 if (Validate(item.Key))
48 {
49 // find a reusable object
50 _unlocked.Remove(item.Key);
51 _locked.Add(item.Key, DateTime.UtcNow);
52 reusable = item.Key;
53 break;
54 }
55 else
56 {
57 // object failed validation
58 _unlocked.Remove(item.Key);
59 Expire(item.Key);
60 }
61 }
62 }
63 }
64
65 // no object available, create a new one
66 if (reusable == null)
67 {
68 reusable = Create();
69 _locked.Add(reusable, DateTime.UtcNow);
70 }
71
72 return reusable;
73 }
74 }
75
76 public void CheckIn(T reusable)
77 {
78 lock (_sync)
79 {
80 _locked.Remove(reusable);
81 _unlocked.Add(reusable, DateTime.UtcNow);
82 }
83 }
84 }
85
86 public class DatabaseConnection : IDisposable
87 {
88 // do some heavy works
89 public DatabaseConnection(string connectionString)
90 {
91 }
92
93 public bool IsOpen { get; set; }
94
95 // release something
96 public void Dispose()
97 {
98 }
99 }
100
101 public class DatabaseConnectionPool : ObjectPool<DatabaseConnection>
102 {
103 private string _connectionString;
104
105 public DatabaseConnectionPool(string connectionString)
106 : base(TimeSpan.FromMinutes(1))
107 {
108 this._connectionString = connectionString;
109 }
110
111 protected override DatabaseConnection Create()
112 {
113 return new DatabaseConnection(_connectionString);
114 }
115
116 public override void Expire(DatabaseConnection connection)
117 {
118 connection.Dispose();
119 }
120
121 public override bool Validate(DatabaseConnection connection)
122 {
123 return connection.IsOpen;
124 }
125 }
126
127 public class Client
128 {
129 public static void TestCase1()
130 {
131 // Create the ConnectionPool:
132 DatabaseConnectionPool pool = new DatabaseConnectionPool(
133 "Data Source=DENNIS;Initial Catalog=TESTDB;Integrated Security=True;");
134
135 // Get a connection:
136 DatabaseConnection connection = pool.CheckOut();
137
138 // Use the connection
139
140 // Return the connection:
141 pool.CheckIn(connection);
142 }
143 }
144 }

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

Object Pool的更多相关文章

  1. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  2. .NET Core中Object Pool的简单使用

    前言 复用,是一个重要的话题,也是我们日常开发中经常遇到的,不可避免的问题. 举个最为简单,大家最为熟悉的例子,数据库连接池,就是复用数据库连接. 那么复用的意义在那里呢? 简单来说就是减少不必要的资 ...

  3. What are the differences between Flyweight and Object Pool patterns?

    What are the differences between Flyweight and Object Pool patterns? They differ in the way they are ...

  4. Object Pool 对象池的C++11使用(转)

    很多系统对资源的访问快捷性及可预测性有严格要求,列入包括网络连接.对象实例.线程和内存.而且还要求解决方案可扩展,能应付存在大量资源的情形. object pool针对特定类型的对象循环利用,这些对象 ...

  5. 对象池模式(Object Pool Pattern)

    本文节选自<设计模式就该这样学> 1 对象池模式的定义 对象池模式(Object Pool Pattern),是创建型设计模式的一种,将对象预先创建并初始化后放入对象池中,对象提供者就能利 ...

  6. Unity Object Pool完全体

    using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public ...

  7. [译]Unity3D内存管理——对象池(Object Pool)

    原文地址:C# Memory Management for Unity Developers (part 3 of 3), 其实从原文标题可以看出,这是一系列文章中的第三篇,前两篇讲解了从C#语言本身 ...

  8. Java小对象的解决之道——对象池(Object Pool)的设计与应用

    一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...

  9. thinking in object pool

    1.背景 对象池为了避免频繁创建耗时或耗资源的大对象,事先在对象池中创建好一定数量的大对象,然后尽量复用对象池中的对象,用户用完大对象之后放回对象池. 2.问题 目前纵观主流语言的实现方式无外乎3个步 ...

随机推荐

  1. Android IPC通信和AIDL技术应用

    首先我们了解一下 IPC和AIDL IPC:进程间通信 AIDL:Android Interface Definition Language,即Android接口定义语言. 为什么使用: Androi ...

  2. ios正在使用NSDateComponents、NSDate、NSCalendar它的结论是在当前时间是在一段时间在一天。

    一般应用程序设置这一组的存在,比如夜间模式,如果你.从8:00-23:00.在这个当前的时间是如何推断出期间.主要的困难在于如何使用NSDate生成8:00时间和23:00时间.然后用当前时间,也许有 ...

  3. Python入门教程 超详细1小时学会Python(转)

    假设我们有这么一项任务:简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200. 思路:用shell编程.(Linux通常是bash而Windows ...

  4. nyoj 517 最小公倍数 【java睑板】

    我写了一个gcd TL该.然后调用math内gcd,AC该... 思维:它是采取n前面的最小公倍数和n求 1~n的最小公倍数 代码: import java.util.Scanner; import ...

  5. 自定义Data Service Providers

    自定义Data Service Providers 作者:AlexJ 翻译:谈少民 原文链接:http://blogs.msdn.com/b/alexj/archive/2010/01/07/data ...

  6. tableView 短剪线离开15像素问题

    ios7于,UITableViewCell左将默认15空白像素. 建立setSeparatorInset:UIEdgeInsetsZero 空白可以去除. ios8中.setSeparatorInse ...

  7. UVA11983 - Weird Advertisement(扫描线)

    UVA11983 - Weird Advertisement(扫描线) 题目链接 题目大意:给你n个覆盖矩形,问哪些整数点是被覆盖了k次. 题目大意:这题和hdu1542是一个题型.可是这题求的是覆盖 ...

  8. POJ 2081 Recaman&#39;s Sequence(水的问题)

    [简要题意]:这个主题是很短的叙述性说明.挺easy. 不重复. [分析]:只需要加一个判断这个数是否可以是一个数组,这个数组的范围. // 3388K 0Ms #include<iostrea ...

  9. jquery扩展

    jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级 ...

  10. C#按LastID进行分页——与lambda形成链式

    public static class PageHelper { /// <summary> /// 按页码分页 /// </summary> /// <param na ...