
Để triển khai mẫu singleton trong C# cần:
- Khai báo constructor riêng (private) không có tham số tránh việc khởi tạo từ ngoài lớp
- Khai báo lớp là sealed để nó không được kế thừa, hữu ích trong trường hợp các lớp lồng nhau
- Tạo biến tĩnh riêng để giữ tham chiếu đến singleton của lớp
Tạo phương thức để lấy thực thể lớp, kiểm tra có tồn tại hoặc tạo mới khi chưa tồn tại
Tôi có tạo một ví dụ sau
Đầu tiên tạo một Project chính và một Project ClassLibrary, trong project Library tạo một lớp Logger như sau
namespace ClassLibrary1.SingletonDesignPattern
{
public sealed class Logger
{
// Khởi tạo ref đến Logger
private static Logger? intance = null;
// Dùng private constructor để tránh khởi tạo từ bên ngoài
private Logger(){}
// Phương thức kiểm tra và khởi tạo thực thể
public static Logger GetIntance()
{
if (intance == null)
{
intance = new Logger();
}
return intance;
}
// Phương thức test
public void log(string message)
{
Console.WriteLine(message);
}
}
}
Sau đó ở chương trình chính, Reference đến ClassLibrary và sử dụng Logger
using ClassLibrary1.SingletonDesignPattern;
namespace SingletonDesignPattern
{
internal class Program
{
static void Main(string[] args)
{
// tạo hai thực thể như thật sự chỉ tạo ra một
Logger logger = Logger.GetIntance();
Logger logger1 = Logger.GetIntance();
// lấy địa chỉ xem để chứng tỏ chúng là 1 thực thể vì có mã hash như nhau
var addressLogger = logger.GetHashCode();
var addressLogger1 = logger1.GetHashCode();
//In ra kết quả
logger.log($"Hello, My name is John - {addressLogger}");
logger1.log($"Hello, My name is Dustin - {addressLogger1}");
}
}
}
Một ví dụ nhanh khác về triển khai singleton
public class Database
{
private static Database _instance;
private static readonly object _lock = new object();
private Database()
{
// Khởi tạo kết nối cơ sở dữ liệu
}
// dùng lock để đảm bảo tại một thời điểm chỉ có 1 luồng được truy cập đến code bên trong nó
public static Database Instance
{
get
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Database();
}
return _instance;
}
}
}
// Các phương thức truy cập và thao tác với cơ sở dữ liệu
}
public class MainClass
{
public static void Main(string[] args)
{
var database1 = Database.Instance;
var database2 = Database.Instance;
// database1 và database2 là cùng một thể hiện
}
}
Post a Comment