*參考資料
** 設計模式
回目錄
以下還沒想到可以用在那裡?
*檔案 Command.cs
using System;
using System.Collections.Generic;
namespace ObjectOriented.DesignPatterns
{
public interface Command<TObj, TArgs>
{
public abstract void ExecCommand(TObj target, TArgs args);
}
abstract class Executor<TKey, TObj, TArgs>
{
private Dictionary<TKey, Command<TObj, TArgs>> buffer = new Dictionary<TKey, Command<TObj, TArgs>>();
protected abstract void Init();
protected abstract void OnError(Command<TObj, TArgs> cmd, Exception ex);
public void Exec(TObj target, TKey key, TArgs args)
{
Command<TObj, TArgs> cmd = null;
try
{
cmd = buffer[key];
cmd.ExecCommand(target, args);
}
catch (Exception ex)
{
OnError(cmd, ex);
}
}
}
}
*檔案 ObjectPool.cs
using System;
using System.Threading;
using System.Collections.Generic;
namespace ObjectOriented.DesignPatterns
{
abstract class ObjectPool<TValue> where TValue : class
{
private Queue<TValue> buffer = new Queue<TValue>();
private SpinLock _spinLock = new SpinLock();
private bool lockTaken = false;
public ObjectPool(int capacity = 1)
{
for (int i=0; i<capacity; i++)
buffer.Enqueue(CreateObject());
}
protected abstract TValue CreateObject();
public TValue GetObject()
{
try
{
_spinLock.Enter(ref lockTaken);
if (buffer.Count != 0)
{
return buffer.Dequeue();
}
else
{
return CreateObject();
}
}
finally
{
if (lockTaken) _spinLock.Exit();
}
}
public void Release(TValue obj)
{
try
{
_spinLock.Enter(ref lockTaken);
buffer.Enqueue(obj);
}
finally
{
if (lockTaken) _spinLock.Exit();
}
}
}
}
*檔案 ShareObjec.cs
using System;
using System.Collections.Generic;
using System.Threading;
namespace ObjectOriented.DesignPatterns
{
abstract class ShareObject<TKey>
{
public TKey ID { get; set; }
private int refCount = 0;
private ShareObject()
{
}
public int AddRef()
{
return Interlocked.Increment(ref refCount);
}
public int Release()
{
return Interlocked.Decrement(ref refCount);
}
}
abstract class ShareObjectPool<TKey, TValue> where TValue : class
{
private Dictionary<TKey, TValue> buffer = new Dictionary<TKey, TValue>();
private SpinLock _spinLock = new SpinLock();
private bool lockTaken = false;
private ShareObjectPool()
{
}
protected abstract TValue CreateObject(TKey ID);
public TValue GetObject(TKey ID)
{
try
{
_spinLock.Enter(ref lockTaken);
TValue result = null;
if (buffer.TryGetValue(ID, out result))
{
(result as ShareObject<TKey>).AddRef();
return result;
}
else
{
result = CreateObject(ID);
buffer.Add(ID, result);
return result;
}
}
finally
{
if (lockTaken) _spinLock.Exit();
}
}
public void Release(TValue obj)
{
try
{
_spinLock.Enter(ref lockTaken);
ShareObject<TKey> obj2 = obj as ShareObject<TKey>;
if (obj2.Release() == 0)
{
buffer.Remove(obj2.ID);
}
}
finally
{
if (lockTaken) _spinLock.Exit();
}
}
}
}