參考ObjectPool對象池設計原理還原一個簡易的Provider模式。html
using System; using System.Dynamic; using System.Reflection.Metadata.Ecma335; using System.Threading; using System.Xml; namespace ProviderPattern { /// <summary> /// 目標 /// </summary> /// <typeparam name="T"></typeparam> public class TargetClass<T> where T:class { private ObjectWrapper[] _items; private ITargetClassPolicy<T> _policy; public TargetClass(ITargetClassPolicy<T> policy) { _policy = policy; _items = new ObjectWrapper[3]; } public T Get() { var items = _items; for (var i = 0; i < items.Length; i++) { var item = items[i].Element; if (item != null && Interlocked.CompareExchange(ref items[i].Element, null,item) != null) { return item; } } return Create(); } public void Return(T obj) { if (!_policy.Return(obj)) { return; } var items = _items; for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null; ++i) { } } private T Create() => _policy.Create(); private struct ObjectWrapper { public T Element; } } /// <summary> /// Provider 提供者 /// </summary> public class TargetClassProvider { public TargetClass<T> Create<T>(ITargetClassPolicy<T> policy) where T : class, new() { return new TargetClass<T>(policy); } } /// <summary> /// Policy 策略 規範 /// </summary> /// <typeparam name="T"></typeparam> public interface ITargetClassPolicy<T> { T Create(); bool Return(T obj); } /// <summary> /// Policy 具體策略類 /// </summary> /// <typeparam name="T"></typeparam> public class TargetClassPolicy<T> : ITargetClassPolicy<T> where T : class, new() { public T Create() { return new T(); } public bool Return(T obj) { return true; } } class User { public string Name { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { var target = new TargetClass<User>(new TargetClassPolicy<User>()); var get = target.Get(); Console.WriteLine($"{get.Name},{get.Age}"); var user1 = new User() { Age = 18, Name = "MicroHeart" }; var user2 = new User() { Age = 19, Name = "MicroHeart" }; var user3 = new User() { Age = 20, Name = "MicroHeart" }; target.Return(user1); target.Return(user2); target.Return(user3); var get1 = target.Get(); Console.WriteLine($"{get1.Name},{get1.Age}"); var get2 = target.Get(); Console.WriteLine($"{get2.Name},{get2.Age}"); Console.Read(); } } }
存儲對象的數組ObjectWrapper內元素的取、還操做經過Interlock.CompareExchange巧妙的實現,而且是線程安全的。設計模式
取操做:Interlocked.CompareExchange(ref items[i].Element, null,item)
。取完後將元素置爲null數組
還操做:Interlocked.CompareExchange(ref items[i].Element, obj, null)
若是元素爲null,則賦值安全
設計原理:經過Policy構建Provider,經過Provider建立最終的目標類(target)。app
參考連接:ObjectPool 對象池設計模式ide