OK, let's go!
UML Class Diagram

sample one:
//This structural code demonstrates the Singleton pattern
//which assures only a single instance (the singleton) of the class can be created.
namespace SingletonPetternTest
{
class Singleton
{
private static Singleton instance;
protected Singleton()
{ }
public static Singleton Instance()
{
//use "lazy initialization"
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.Instance();
Singleton s2 = Singleton.Instance();
if (s1 == s2)
{
Console.WriteLine("objects are the same instance...");
}
}
}
}
sample two:
This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go throught the one object that has knowledge about the state of the (web) farm.
// Singleton pattern -- Real World example
using System;
using System.Collections;
using System.Threading;
namespace DoFactory.GangOfFour.Singleton.RealWorld
{
// MainApp test application
class MainApp
{
static void Main()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// All are the same instance -- use b1 arbitrarily
// Load balance 15 server requests
for (int i = 0; i < 15; i++)
{
Console.WriteLine(b1.Server);
}
// Wait for user
Console.Read();
}
}
// "Singleton"
class LoadBalancer
{
private static LoadBalancer instance;
private ArrayList servers = new ArrayList();
private Random random = new Random();
// Lock synchronization object
private static object syncLock = new object();
// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
servers.Add("ServerI");
servers.Add("ServerII");
servers.Add("ServerIII");
servers.Add("ServerIV");
servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (instance == null)
{
lock (syncLock)
{
if (instance == null)
{
instance = new LoadBalancer();
}
}
}
return instance;
}
// Simple, but effective random load balancer
public string Server
{
get
{
int r = random.Next(servers.Count);
return servers[r].ToString();
}
}
}
}
sample three:
This .NET optimized code demonstrates the same code as above but uses more modern, built-in .NET features.
Here an elegant .NET specific solution is offered. The Singleton pattern simply uses a private constructor and a static readonly instance variable that is lazily initialized. Thread safety is guaranteed by the compiler.
// Singleton pattern -- .NET optimized
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Singleton.NETOptimized
{
// MainApp test application
class MainApp
{
static void Main()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Confirm these are the same instance
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// All are the same instance -- use b1 arbitrarily
// Load balance 15 requests for a server
for (int i = 0; i < 15; i++)
{
Console.WriteLine(b1.Server);
}
// Wait for user
Console.Read();
}
}
// Singleton
sealed class LoadBalancer
{
// Static members are lazily initialized.
// .NET guarantees thread safety for static initialization
private static readonly LoadBalancer instance =
new LoadBalancer();
private ArrayList servers = new ArrayList();
private Random random = new Random();
// Note: constructor is private.
private LoadBalancer()
{
// List of available servers
servers.Add("ServerI");
servers.Add("ServerII");
servers.Add("ServerIII");
servers.Add("ServerIV");
servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
return instance;
}
// Simple, but effective load balancer
public string Server
{
get
{
int r = random.Next(servers.Count);
return servers[r].ToString();
}
}
}
}
sample four:
using System.Threading;//
namespace SingletonPetternTest
{
public class Singleton
{
private static readonly Singleton _instance;
private int v;
//protected constructor is sufficient to prevent instantiation by using "new" keyword
protected Singleton()
{
Console.WriteLine("Singleton Instance Creating....");
this.V = 0;
Thread.Sleep(1000);//simulate a heavy creation cost
Console.WriteLine("Singleton Instance Created...");
}
//static constructor
static Singleton()
{
_instance = new Singleton();
}
public static Singleton Instance
{
get
{
return _instance;
}
}
public int V
{
get
{
return v;
}
set
{
v = value;
}
}
public void DoSomeWork()
{
Console.WriteLine("#");
lock (this)
{
V++;
}
Thread.Sleep(500);
}
}
class Program
{
//singleton with multithread
static void MultiThread()
{
Singleton instance = Singleton.Instance;
Thread t = new Thread(new ThreadStart(instance.DoSomeWork));
t.Start();
}
static void Main(string[] args)
{
int i;
for (i = 0; i < 10; i++)
{
Console.WriteLine("Do Some Work...");
Thread.Sleep(100);
}
//until now,this application has no any instance
for (i = 0; i < 300; i++)
{
MultiThread();
}
Thread.Sleep(1000); // wait for sure all threads finished
Console.WriteLine();
Console.WriteLine("V value expected: "+i+" actual value is : "+Singleton.Instance.V);
}
}
}


No comments:
Post a Comment