Singleton and Object Pools(Thinking in Patterns)
Possibly the simplest design pattern is the singleton, which is a way to provide one and only one object of a particular type. An important aspect of Singleton is that you provide a global access point.
The key to creating a singleton is to prevent the client programmer from having any way to create an object except the ways you provide. You must make all constructors private, and you must create at least one constructor to prevent the compiler from synthesizing a default constructor for you (which it will create using package access).Java also allows the creation of objects through cloning. In this example, making the class final prevents cloning.(For .Net ,you should also attention the mothod - MemberwiseClone()).
Example:
using System;
using System.Threading;
class Singleton
{
private static Singleton instance;
private Singleton() {}
// Methods
public static Singleton Instance()
{
// Only one thread can obtain a mutex
Mutex mutex = new Mutex();
mutex.WaitOne();
// Uses "Lazy initialization"
if( instance == null )
instance = new Singleton();
mutex.Close();
return instance;
}
}
Object pool
Note that you aren’t restricted to creating only one object. This is also a technique to create a limited pool of objects. In that situation, however, you can be confronted with the problem of sharing objects in the pool. If this is an issue, you can create a solution involving a check-out and check-in of the shared objects.
Example:
using System;
using System.Collections;
namespace ObjectPool
{
public class PoolManager
{
private class PoolItem
{
public bool inUse = false;
public Object item;
public PoolItem(Object item) { this.item = item; }
}
private ArrayList items = new ArrayList();
public void add(Object item)
{
items.Add(new PoolItem(item));
}
public class EmptyPoolException :Exception {}
public Object getItem()
{
for(int i = 0; i < items.Count; i++)
{
PoolItem pitem = (PoolItem)items[i];
if(pitem.inUse == false) {
pitem.inUse = true;
return pitem.item;
}
}
// Fail early:
throw (new EmptyPoolException());
// return null; // Delayed failure
}
public void release(Object item)
{
for(int i = 0; i < items.Count; i++)
{
PoolItem pitem = (PoolItem)items[i];
if(item == pitem.item) {
pitem.inUse = false;
return;
}
}
throw new Exception(item + " not found");
}
}
}
Using the PoolManager to host connections:
using System;
namespace ObjectPool
{
interface Connection
{
Object Get();
void Set(Object x);
}
class ConnectionImplementation : Connection
{
public Object Get() { return null; }
public void Set(Object s) {}
}
class ConnectionPool
{ // A singleton
private static PoolManager pool = new PoolManager();
public static void addConnections(int number)
{
for(int i = 0; i < number; i++)
pool.add(new ConnectionImplementation());
}
public static Connection getConnection()
{
return (Connection)pool.getItem();
}
public static void releaseConnection(Connection c)
{
pool.release(c);
}
}
public class ConnectionPoolDemo
{
public static void Main(String[] args)
{
Connection c = null;
try {
c = ConnectionPool.getConnection();
}
catch (PoolManager.EmptyPoolException e)
{
throw new Exception("",e);
}
c.Set(new Object());
c.Get();
ConnectionPool.releaseConnection(c);
}
}
}
浙公网安备 33010602011771号