Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored Singleton Pattern examples for compatibility and thread sa… #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,8 @@ public class SingletonPatternExample1 : MonoBehaviour
{
void Start()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
var balancer = LoadBalancer.Instance;

// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Debug.Log("Same instance\n");
}

// Load balance 15 server requests
LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
for (int i = 0; i < 15; i++)
{
string server = balancer.Server;
Expand All @@ -37,56 +26,39 @@ void Start()
}
}

/// <summary>
/// The 'Singleton' class
/// </summary>
class LoadBalancer
public sealed class LoadBalancer
{
private static readonly object _syncLock = new object();
private static LoadBalancer _instance;
private List<string> _servers = new List<string>();
private System.Random _random = new System.Random();

// Lock synchronization object
private static object syncLock = new object();
private readonly List<string> _servers = new List<string> { "ServerI", "ServerII", "ServerIII", "ServerIV", "ServerV" };
private readonly System.Random _random = new System.Random();

// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
private LoadBalancer() { }

public static LoadBalancer GetLoadBalancer()
public static LoadBalancer Instance
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (_instance == null)
get
{
lock (syncLock)
if (_instance == null)
{
if (_instance == null)
lock (_syncLock)
{
_instance = new LoadBalancer();
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}

return _instance;
}

// Simple, but effective random load balancer
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
return _servers[r];
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,27 @@ void Update()
}
}


/// <summary>
/// 某单例manager
/// </summary>
public class RenderManager
public sealed class RenderManager
{
private static RenderManager instance;
private static RenderManager _instance;

private RenderManager() { }

public static RenderManager Instance
{
get
{
if (instance == null)
if (_instance == null)
{
instance = new RenderManager();
_instance = new RenderManager();
}
return instance;
return _instance;
}
}

/// <summary>
/// 随便某方法
/// </summary>
public void Show()
{
Debug.Log("RenderManager is a Singleton !");
Debug.Log("RenderManager is a Singleton!");
}
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,52 @@

namespace SingletonPatternExample3
{

public class SingletonPatternExample3 : MonoBehaviour
{
void Start()
{
//单例A
SingletonA.Instance.DoSomething();

//单例B
SingletonB.Instance.DoSomething();
}

}

/// <summary>
/// 单例类基类(抽象类、泛型,其他类只需继承此类即可成为单例类)
/// 继承该类的,即成为一个单例类
/// </summary>
public abstract class Singleton<T>
where T : class, new()
public abstract class Singleton<T> where T : class, new()
{
private static T _instance = null;
private static readonly object _syncLock = new object();
private static T _instance;

public static T Instance
{
get
{
if (_instance == null)
{
_instance = new T();
return _instance;
lock (_syncLock)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}

protected virtual void Awake()
{
_instance = this as T;
}
}


/// <summary>
/// 继承自Singleton<T>的单例
/// </summary>
public class SingletonA : Singleton<SingletonA>
{
public void DoSomething()
{
Debug.Log("SingletonA:DoSomething!");
Debug.Log("SingletonA: DoSomething!");
}
}

/// <summary>
/// 继承自Singleton<T>的单例
/// </summary>
public class SingletonB : Singleton<SingletonB>
{
public void DoSomething()
{
Debug.Log("SingletonB:DoSomething!");
Debug.Log("SingletonB: DoSomething!");
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,33 @@

public class SingletonStructure : MonoBehaviour
{

void Start()
{
// Constructor is protected -- cannot use new
Singleton s1 = Singleton.Instance();
Singleton s2 = Singleton.Instance();
var s1 = Singleton.Instance;
var s2 = Singleton.Instance;

// Test for same instance
if (s1 == s2)
{
Debug.Log("Objects are the same instance");
}
}
}

/// <summary>
/// The 'Singleton' class
/// </summary>
class Singleton
public class Singleton
{
private static Singleton _instance;

// Constructor is 'protected'
protected Singleton()
{
}
protected Singleton() { }

public static Singleton Instance()
public static Singleton Instance
{
// Uses lazy initialization.
// Note: this is not thread safe.
if (_instance == null)
get
{
_instance = new Singleton();
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}

return _instance;
}
}
17 changes: 10 additions & 7 deletions Unity-Design-Pattern.sln
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity-Design-Pattern", "Unity-Design-Pattern.csproj", "{AA5D6718-EC1F-D1EA-526D-52AF3C037FBB}"
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity-Design-Pattern", "Assembly-CSharp.csproj", "{8ABF50DE-5C45-E1BE-2FA5-8FD59671116B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA5D6718-EC1F-D1EA-526D-52AF3C037FBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA5D6718-EC1F-D1EA-526D-52AF3C037FBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA5D6718-EC1F-D1EA-526D-52AF3C037FBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA5D6718-EC1F-D1EA-526D-52AF3C037FBB}.Release|Any CPU.Build.0 = Release|Any CPU
{8ABF50DE-5C45-E1BE-2FA5-8FD59671116B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8ABF50DE-5C45-E1BE-2FA5-8FD59671116B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8ABF50DE-5C45-E1BE-2FA5-8FD59671116B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8ABF50DE-5C45-E1BE-2FA5-8FD59671116B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
EndGlobalSection
EndGlobal