Provider模式應用demo

參考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

相關文章
相關標籤/搜索