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 一.相关配置 ...
随机推荐
- Spring中常见的设计模式——单例模式
一.单例模式的应用场景 单例模式(singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.J2EE中的ServletContext,ServletCon ...
- Tomcat安装和使用
1.Tomcat简介 Tomcat是Apache开源组织下的开源免费的中小型Web应用服务器,支持javaEE中的servlet和jsp规范. 2.Windows版安装和使用 下载地址:http:// ...
- day 19 os模块的补充 序列化 json pickle
os 模块 os.path.abspath 规范绝对路径 os.path.split() 把路径分成两段,第二段是一个文件或者是文件夹 os.path.dirname 取第一部分 os.p ...
- mysql如何设置主从(读写分离),redis发布功能,以及redis的持久化存储(rdb,aof)
1 mysql基本命令 1.启动mysql systemctl start mariadb 2.linux客户端连接自己 mysql -uroot -p -h 127.0.0.1 3.远程链接mysq ...
- 机器学习实战书-第二章K-近邻算法笔记
本章介绍第一个机器学习算法:A-近邻算法,它非常有效而且易于掌握.首先,我们将探讨女-近邻算法的基本理论,以及如何使用距离测量的方法分类物品:其次我们将使用?7««^从文本文件中导人并解析数据: 再次 ...
- PAT(甲级)2017年秋季考试
PAT(甲级)2017年秋季考试 D题红黑树待补21/30 大佬的代码,看着想哭,这才是艺术啊 A Cut Integer 模拟题 #include<bits/stdc++.h> usin ...
- 3分钟了解ServiceStage 应用智能化运维【华为云分享】
[摘要] 微服务云应用平台(ServiceStage)是面向企业及开发者的一站式DevOps平台服务,支持基于微服务的应用开发.治理.部署及运维监控的全生命周期管理,并提供大规模容器集群管理及中间件服 ...
- 分析Crash文件
应用在没有发布前,可以通过打印log很方便的查看错误信息.但是发布后,就需要根据Crash文件来定位了. 将手机连接电脑,通过XCode获取Crash文件.Window ->Devices -& ...
- mininet(一)实验环境搭建
mininet(一)实验环境搭建 mininet(二)简单的路由实验 mininet(三)简单的NAT实验 最近学习(https://github.com/mininet/openflow-tutor ...
- vuex模块化。
项目结构: 1:在src下新建目录store,然后再建storemodule.js文件,把 上篇 store.js文件抽出来: import Vue from 'vue' import Vuex fr ...