Provider模式应用demo
参考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的更多相关文章
- wemall app商城源码Android之Native(原生)支付模式一demo
wemall-mobile是基于WeMall的Android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享Native(原生)支付模式一demo,供技术 ...
- ASP.NET Provider模式应用之SqlMembershipProvider类的剖析
太多了,先给个流程图吧 Provider模式就是GOF中的两种设计模式的应用:策略模式和工厂模式,在程序中使用好这个模型能够解除模块与模块之间的耦合甚至是DIP,同时,不管是ASP.NET MVC还是 ...
- Provider 模式
Provider 模式:为一个API进行定义和实现的分离. 常见场景:DBPrider切换,第3方集成API切换 以发邮件为例: Email Provider Config: public abstr ...
- provider模式
最近看代码有所感想吧.当底层API,发生变化时,可以使用Provider模式.既然是模式就一定的股则. 1.该模式对原有接口的封装. 2.该模式实现对API的封装,不显示细节,从而取消依赖关系. 3. ...
- Pipeline模式与Factory+Provider模式的应用
前言 我正在写FastGithub这个小麻雀项目,里面主要涉及了Pipeline模式和Factory+Provider模式,这两种设计模式,让这个项目在"ip扫描"和"i ...
- hasura graphql 模式拼接demo
实际上通过上边的介绍,模式拼接和hasura 基本没啥关系了,就是使用graphql-bindings 进行schema 合并了 基本demo 这个是官方提供的demo git clone https ...
- 微信公众号 扫码支付 模式二 demo
扫码支付 本文附有代码,在下方,如果不熟悉场景的可以看看下面的场景介绍 场景介绍 官网介绍地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?ch ...
- Service Provider模式
参考文章:[http://blog.csdn.net/zl3450341/article/details/7227197] Service Interface:服务接口,将服务通过抽象统一声明,供客户 ...
- Java微信扫描支付模式二Demo ,整合官网直接运行版本
概述 场景介绍 用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付. 详细 代码下载:http://www.demodashi.com/demo/13880.html 一.相关配置 ...
随机推荐
- 程序员用于机器学习数据科学的3个顶级 Python 库
NumPy NumPy(数值 Python 的简称)是其中一个顶级数据科学库,它拥有许多有用的资源,从而帮助数据科学家把 Python 变成一个强大的科学分析和建模工具.NumPy 是在 BSD 许可 ...
- echarts对柱状图进行标注,以及取消hover时的阴影
option = { color: ['#3398DB'], tooltip : { trigger: 'axis', axisPointer : { // 坐标轴指示器,坐标轴触发有效 type : ...
- Dockerfile构建私有镜像
构建第一个镜像 镜像的定制实际上就是定制每一层所添加的配置,文件.我们可以把每一层修改,安装,构建,操作的命令都写入一个脚本,这个脚本就是Dockerfile.Dockerfile是一个文本文件,其内 ...
- python初识-环境搭建,变量,条件,循环语句
1.python环境搭建: (1)安装Anaconda ,可选择非C盘安装: 注意:都勾选: (2)安装Pycharm 默认安装即可,安装过程同样都勾选: (3)破解Pycharm https://w ...
- diff()函数的使用
1.diff():返回略微迭代(lagged)的或滞后的不同(iterated diferences). > x<-cumsum(cumsum(1:10)) > x [1] 1 4 ...
- 【JZOJ】3490. 旅游题解报告
题目 思路 这道题看上去就像一个动态规划!但是还是要把矩阵压成一行. 然后按 \(A\)数组 将结构体从小到大排个序. 随后我们开始了动规标准步骤: 确定状态 很显然, \(f_i\) 表示游览完第\ ...
- Oracle触发器用法--基础教学
1.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好了.这里面需 ...
- luogu P1731 [NOI1999]生日蛋糕 |暴力枚举
题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱 ...
- luogu P3830 [SHOI2012]随机树
输入格式 输入仅有一行,包含两个正整数 q, n,分别表示问题编号以及叶结点的个数. 输出格式 输出仅有一行,包含一个实数 d,四舍五入精确到小数点后 6 位.如果 q = 1,则 d 表示叶结点平均 ...
- tableview封装使用
下载地址 使用方法 1. #import "ZFTableView.h" 2.在需要使用的地方添加ZFTableView 如下 ZFTableView *ta ...