CSharp: Singleton Pattern in donet core 3
/// <summary>
/// 单例模式 Singleton Pattern
/// geovindu,Geovin Du edit
/// </summary>
public class Database
{
/// <summary>
///
/// </summary>
private Database()
{
}
/// <summary>
///
/// </summary>
public static Database Instance { get; } = new Database();
}
/// <summary>
///
/// </summary>
public class MyDatabase
{
/// <summary>
///
/// </summary>
private MyDatabase()
{
Console.WriteLine("Initializing database");
}
/// <summary>
///
/// </summary>
private static Lazy<MyDatabase> instance =
new Lazy<MyDatabase>(() => new MyDatabase());
/// <summary>
///
/// </summary>
public static MyDatabase Instance => instance.Value;
}
/// <summary>
///
/// </summary>
public interface IDatabase
{
int GetPopulation(string name);
}
/// <summary>
///
/// </summary>
public class SingletonDatabase : IDatabase
{
/// <summary>
///
/// </summary>
private Dictionary<string, int> capitals;
/// <summary>
///
/// </summary>
private static int instanceCount;
/// <summary>
///
/// </summary>
public static int Count => instanceCount;
/// <summary>
///
/// </summary>
private SingletonDatabase()
{
Console.WriteLine("Initializing database");
capitals = File.ReadAllLines(
Path.Combine(
new FileInfo(typeof(IDatabase).Assembly.Location)
.DirectoryName,
"capitals.txt")
)
.Batch(2)
.ToDictionary(
list => list.ElementAt(0).Trim(),
list => int.Parse(list.ElementAt(1)));
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public int GetPopulation(string name)
{
return capitals[name];
}
/// <summary>
/// laziness + thread safety
/// </summary>
private static readonly Lazy<SingletonDatabase> instance
= new Lazy<SingletonDatabase>(() =>
{
instanceCount++;
return new SingletonDatabase();
});
public static IDatabase Instance => instance.Value;
}
/// <summary>
///
/// </summary>
public class SingletonRecordFinder
{
/// <summary>
///
/// </summary>
/// <param name="names"></param>
/// <returns></returns>
public int TotalPopulation(IEnumerable<string> names)
{
return names.Sum(name => SingletonDatabase.Instance.GetPopulation(name));
}
}
/// <summary>
///
/// </summary>
public class ConfigurableRecordFinder
{
/// <summary>
///
/// </summary>
private IDatabase database;
/// <summary>
///
/// </summary>
/// <param name="database"></param>
public ConfigurableRecordFinder(IDatabase database)
{
this.database = database;
}
/// <summary>
///
/// </summary>
/// <param name="names"></param>
/// <returns></returns>
public int GetTotalPopulation(IEnumerable<string> names)
{
return names.Sum(name => database.GetPopulation(name));
}
}
/// <summary>
///
/// </summary>
public class DummyDatabase : IDatabase
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public int GetPopulation(string name)
{
return new Dictionary<string, int>
{
["alpha"] = 1,
["beta"] = 2,
["gamma"] = 3
}[name];
}
}
/// <summary>
///
/// </summary>
public class OrdinaryDatabase : IDatabase
{
/// <summary>
///
/// </summary>
private readonly Dictionary<string, int> cities;
/// <summary>
///
/// </summary>
public OrdinaryDatabase()
{
Console.WriteLine("Initializing database");
cities = File.ReadAllLines(
Path.Combine(
new FileInfo(typeof(IDatabase).Assembly.Location)
.DirectoryName,
"capitals.txt")
)
.Batch(2)
.ToDictionary(
list => list.ElementAt(0).Trim(),
list => int.Parse(list.ElementAt(1)));
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public int GetPopulation(string name)
{
return cities[name];
}
}
/// <summary>
/// 单例模式 Singleton Pattern
/// geovindu,Geovin Du edit
/// </summary>
public sealed class Singleton
{
#region Singleton implementation using static constructor
//The following line is discussed in analysis section.
//private static readonly Singleton Instance = new Singleton();
private static readonly Singleton Instance;
private static int TotalInstances;
/*
* Private constructor is used to prevent
* creation of instances with 'new' keyword
* outside this class.
*/
/// <summary>
///
/// </summary>
private Singleton()
{
Console.WriteLine("--Private constructor is called.");
Console.WriteLine("--Exit now from private constructor.");
}
/*
* A static constructor is used for the following purposes:
* 1. To initialize any static data;
* 2. To perform a specific action only once.
*
* The static constructor will be called automatically before *
* i. You create the first instance; or
* ii.You refer to any static members in your code.
*
*/
/// <summary>
/// Here is the static constructor
/// </summary>
static Singleton()
{
// Printing some messages before you create the instance
Console.WriteLine("-Static constructor is called.");
Instance = new Singleton();
TotalInstances++;
Console.WriteLine($"-Singleton instance is created.Number of instances:{ TotalInstances}");
Console.WriteLine("-Exit from static constructor.");
}
/// <summary>
///
/// </summary>
public static Singleton GetInstance
{
get
{
return Instance;
}
}
/*
* If you like to use expression-bodied read-only
* property, you can use the following line (C# v6.0 onwards).
*/
//public static Singleton GetInstance => Instance;
#endregion
/* The following line is used to discuss
the drawback of the approach. */
/// <summary>
///
/// </summary>
public static int MyInt = 25;
}
调用:
Console.WriteLine("***单例模式 Singleton Pattern Demonstration.***\n");
/*The following line is used to discuss
the drawback of the approach.*/
//Console.WriteLine($"The value of MyInt is :{Singleton.MyInt}");
// Private Constructor.So,you cannot use the 'new' keyword.
//Singleton s = new Singleton(); // error
Console.WriteLine("Trying to get a Singleton instance, called firstInstance.");
Singleton firstInstance = Singleton.GetInstance;
Console.WriteLine("Trying to get another Singleton instance, called secondInstance.");
Singleton secondInstance = Singleton.GetInstance;
if (firstInstance.Equals(secondInstance))
{
Console.WriteLine("The firstInstance and secondInstance are the same.");
}
else
{
Console.WriteLine("Different instances exist.");
}
//
var rf = new SingletonRecordFinder();
var names = new[] { "Seoul", "Mexico City" };
var ci = names[0].ToString();
int tp = rf.TotalPopulation(names);
Console.WriteLine(tp);
var db = new DummyDatabase();
var rf2 = new ConfigurableRecordFinder(db);
int t= rf2.GetTotalPopulation(new[] { "alpha", "gamma" }); ;
Console.WriteLine(t);
db.GetPopulation("gamma");
var db2 = SingletonDatabase.Instance;
// works just fine while you're working with a real database.
var city = "Tokyo";
Console.WriteLine($"{city} has population {db2.GetPopulation(city)}");
Console.WriteLine($"{names[0]} has population {db2.GetPopulation(names[0])}");
Console.Read();
输出:
***单例模式 Singleton Pattern Demonstration.*** Trying to get a Singleton instance, called firstInstance. -Static constructor is called. --Private constructor is called. --Exit now from private constructor. -Singleton instance is created.Number of instances:1 -Exit from static constructor. Trying to get another Singleton instance, called secondInstance. The firstInstance and secondInstance are the same. Initializing database 34900000 4 Tokyo has population 33200000 Seoul has population 17500000
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号