参考ObjectPool对象池设计原理还原一个简易的Provider模式。
using System; using System.Dynamic; using System.Reflection.Metadata.Ecma335; using System.Threading; using System.Xml; namespace ProviderPattern { ////// 目标 //////public class TargetClasswhere T:class { private ObjectWrapper[] _items; private ITargetClassPolicy_policy; public TargetClass(ITargetClassPolicypolicy) { _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; } } ////// Provider 提供者 ///public class TargetClassProvider { public TargetClassCreate(ITargetClassPolicypolicy) where T : class, new() { return new TargetClass(policy); } } ////// Policy 策略 规范 //////public interface ITargetClassPolicy{ T Create(); bool Return(T obj); } ////// Policy 具体策略类 //////public class TargetClassPolicy: ITargetClassPolicywhere 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(new TargetClassPolicy()); 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)。