Object Pool

设计模式之美: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.

结构

Object Pool

 

参与者

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)