参考ObjectPool对象池设计原理还原一个简易的Provider模式。

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)。

参考链接:ObjectPool 对象池设计模式

Provider模式应用demo的更多相关文章

  1. wemall app商城源码Android之Native(原生)支付模式一demo

    wemall-mobile是基于WeMall的Android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享Native(原生)支付模式一demo,供技术 ...

  2. ASP.NET Provider模式应用之SqlMembershipProvider类的剖析

    太多了,先给个流程图吧 Provider模式就是GOF中的两种设计模式的应用:策略模式和工厂模式,在程序中使用好这个模型能够解除模块与模块之间的耦合甚至是DIP,同时,不管是ASP.NET MVC还是 ...

  3. Provider 模式

    Provider 模式:为一个API进行定义和实现的分离. 常见场景:DBPrider切换,第3方集成API切换 以发邮件为例: Email Provider Config: public abstr ...

  4. provider模式

    最近看代码有所感想吧.当底层API,发生变化时,可以使用Provider模式.既然是模式就一定的股则. 1.该模式对原有接口的封装. 2.该模式实现对API的封装,不显示细节,从而取消依赖关系. 3. ...

  5. Pipeline模式与Factory+Provider模式的应用

    前言 我正在写FastGithub这个小麻雀项目,里面主要涉及了Pipeline模式和Factory+Provider模式,这两种设计模式,让这个项目在"ip扫描"和"i ...

  6. hasura graphql 模式拼接demo

    实际上通过上边的介绍,模式拼接和hasura 基本没啥关系了,就是使用graphql-bindings 进行schema 合并了 基本demo 这个是官方提供的demo git clone https ...

  7. 微信公众号 扫码支付 模式二 demo

    扫码支付 本文附有代码,在下方,如果不熟悉场景的可以看看下面的场景介绍 场景介绍 官网介绍地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?ch ...

  8. Service Provider模式

    参考文章:[http://blog.csdn.net/zl3450341/article/details/7227197] Service Interface:服务接口,将服务通过抽象统一声明,供客户 ...

  9. Java微信扫描支付模式二Demo ,整合官网直接运行版本

    概述 场景介绍 用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付. 详细 代码下载:http://www.demodashi.com/demo/13880.html 一.相关配置 ...

随机推荐

  1. Spring Security框架下实现两周内自动登录"记住我"功能

    本文是Spring Security系列中的一篇.在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户.角色.权限相关信息,从而实 ...

  2. Hadoop之HDFS文件系统(二)

    HDFS客户端 通过IO流操作HDFS HDFS文件上传 @Test public void putFileToHDFS() throws Exception{ // 1 创建配置信息对象 Confi ...

  3. python3基础之 字符串切片

    一.python3中,可迭代对象有:列表.元组.字典.字符串:常结合for循环使用:均可使用索引切片 实例: str = ' #str[start:stop:step] 遵循[左闭右开]规则 prin ...

  4. Fortran文件读写--查找内容

    program ex implicit none character(len=) A(),B(),C() !A异常.B已开挖.C需标记 integer i,j,N1,N2,count !N1是10号文 ...

  5. day 32 操作系统、线程和进程(GIL锁)

    一.操作系统/应用程序 a. 硬件 - 硬盘 - CPU - 主板 - 显卡 - 内存 - 电源 ... b. 装系统(软件) - 系统就是一个由程序员写出来软件,该软件用于控制计算机的硬件,让他们之 ...

  6. Java中的集合(Set,List,Map)

    ******************collections类总结*************************** JAVA集合主要分为三种类型:    Set(集)    List(列表)    ...

  7. Log4net 使用汇总(网络收集整理)

    原帖1:http://blog.csdn.net/wanzhuan2010/article/details/7587780 原帖2:http://grim1980.blog.sohu.com/2555 ...

  8. JQuery动态添加控件并取值

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. make命令和makefile

    make命令和Makefiles: 1. make是一个命令,解释makefile中指令的命令工具,不同的IDE有自己的make命令. 1. make命令不知道怎么去构建程序,必须有一个文件告诉mak ...

  10. Flask开发天气查询软件,带你掌握pipenv的使用与手机Termux下的部署

    关于pipenv 昨天介绍了pipenv这个相比于virtualenv更高端大气上档次的虚拟环境管理软件,但看了下流量貌似不是很受欢迎,也许是我介绍的不够好吧.那么今天就拿它做一个例子,开发一款天气预 ...