- [SQLSERVER] Loại bỏ Restricted User trên database MSSQL
- [C#] Hướng dẫn tạo mã QRcode Style trên winform
- [C#] Hướng dẫn sử dụng temp mail service api trên winform
- [C#] Hướng dẫn tạo mã thanh toán VietQR Pay không sử dụng API trên winform
- [C#] Hướng Dẫn Tạo Windows Service Đơn Giản Bằng Topshelf
- [C#] Chia sẻ source code đọc dữ liệu từ Google Sheet trên winform
- [C#] Chia sẻ source code tạo mã QR MOMO đa năng Winform
- [C#] Chia sẻ source code phần mềm lên lịch tự động chạy ứng dụng Scheduler Task Winform
- [Phần mềm] Tải và cài đặt phần mềm Sublime Text 4180 full version
- [C#] Hướng dẫn download file từ Minio Server Winform
- [C#] Hướng dẫn đăng nhập zalo login sử dụng API v4 trên winform
- [SOFTWARE] Phần mềm gởi tin nhắn Zalo Marketing Pro giá rẻ mềm nhất thị trường
- [C#] Việt hóa Text Button trên MessageBox Dialog Winform
- [DEVEXPRESS] Chia sẻ code các tạo report in nhiều hóa đơn trên XtraReport C#
- [POWER AUTOMATE] Hướng dẫn gởi tin nhắn zalo từ file Excel - No code
- [C#] Chia sẻ code lock và unlock user trong domain Window
- [DEVEXPRESS] Vẽ Biểu Đồ Stock Chứng Khoán - Công Cụ Thiết Yếu Cho Nhà Đầu Tư trên Winform
- [C#] Hướng dẫn bảo mật ứng dụng 2FA (Multi-factor Authentication) trên Winform
- [C#] Hướng dẫn convert HTML code sang PDF File trên NetCore 7 Winform
- [C#] Hướng dẫn viết ứng dụng chat với Gemini AI Google Winform
[C#] Giới thiệu Singleton trong Design Pattern - Duy nhất một thể hiện
Bài viết hôm nay, mình xin giới thiệu với các bạn về Singleton trong Design Pattern C#.
Vậy Singleton trong Design Pattern C# là gì?
Singleton là một design pattern được sử dụng cũng phổ biến. Nó đưa ra cách thiết kế để đảm bảo rằng chỉ tạo ra không quá một thể hiện của một lớp và thể hiện này có thể được truy cập từ bất cứ đâu.
CÁC THÀNH PHẦN THAM GIA
Trong Singleton chỉ cần xây dựng trên duy nhất một lớp, trên lớp này chia thành 2 nhóm thành phần:
Nhóm đảm bảo chỉ tạo được một thể hiện: hàm khởi tạo là private hoặc protected để không tạo được thể hiện từ bên ngoài. Biến instance là private và static để đảm bảo chỉ có 1 thể hiện. Thuộc tính Instance cung cấp giao diện để truy xuất đến thể hiện duy nhất.
Nhóm nghiệp vụ: chứa các thuộc tính và phương thức nghiệp vụ đặc thù của lớp.
CÀI ĐẶT SINGLETON TRONG C#
Để đơn giản, tôi sẽ không cài đặt nhóm nghiệp vụ cho class Singleton:
class MainApp
{
static void Main()
{
Singleton s1 = Singleton.Instance;
Singleton s2 = Singleton.Instance;
// Kiểm tra xem có đúng 2 biến trỏ đến cùng 1 thể hiện không
if (s1 == s2)
Console.WriteLine("SAME");
Console.ReadKey();
}
}
///
/// The 'Singleton' class
///
class Singleton
{
private static Singleton _instance;
protected Singleton()
{
}
public static Singleton Instance()
{
// nếu chưa có thì tạo thể hiện duy nhất
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
Kết quả:
SAME
Nhận xét:
Singleton sử dụng tính đóng gói, bao bọc (encapsulate) của lập trình hướng đối tượng để che dấu, bảo vệ biến _instance (chỉ khởi tạo và gán duy nhất 1 lần) đồng thời che dấu phương thức khởi tạo với bên ngoài.
MỘT VÍ DỤ TRONG THỰC TẾ
Tôi sẽ lấy ví dụ cho trường hợp cân bằng tải (LoadBalancing) cho server. Bạn có một server chuyên nhận yêu cầu để xử lý và trả về kết quả. Server của bạn chỉ được khoảng 1000 request / giây, nếu trên số đó server của bạn sẽ bị quá tải. Trong thực tế số lượng request lên tới hơn 3000 / giây. Bạn đã đã đầu tư thêm 3 con server mới nữa để đáp ứng và bạn cần có 1 server đúng ra cân bằng tải cho 4 server đúng sau. Trong trường hợp này, server cân bằng tải có thể thiết kế theo Singleton, mọi request đều tham chiếu tới cùng một server cân bằng tải và server này chỉ có 1.
Tôi thực hiện cài đặt giống như mẫu bên trên:
class MainApp
{
static void Main()
{
// Giả lập 15 request
for (var i = 0; i < 15; i++)
{
var balancer = LoadBalancer.GetLoadBalancer();
Console.WriteLine("Chuyen den: " + balancer.Server);
}
Console.ReadKey();
}
}
///
/// The 'Singleton' class
///
class LoadBalancer
{
private static LoadBalancer _instance;
private readonly List _servers = new List();
private readonly Random _random = new Random();
protected LoadBalancer()
{
// Tạo ra 4 server
for (var i = 0; i < 4; i++) _servers.Add("Server " + (i + 1));
}
public static LoadBalancer GetLoadBalancer()
{
if (_instance == null)
_instance = new LoadBalancer();
return _instance;
}
// Trả về ngẫu nhiên 1 server
// Đơn giản nhưng cân bằng tải cũng khá hiệu quả
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r];
}
}
}
Kết quả nhận được sẽ tương tự như sau:
Chuyen den: Server 1
Chuyen den: Server 1
Chuyen den: Server 2
Chuyen den: Server 4
Chuyen den: Server 1
Chuyen den: Server 2
Chuyen den: Server 4
Chuyen den: Server 2
Chuyen den: Server 4
Chuyen den: Server 1
Chuyen den: Server 3
Chuyen den: Server 1
Chuyen den: Server 4
Chuyen den: Server 3
Chuyen den: Server 4
Ở đây, nếu ta để ý thật kỹ đoạn code cài đặt cho phương thức GetLoadBalancer() thì các bạn sẽ thấy có vấn đề khi hàm này được chạy đa luồng. Với ví dụ trên, 15 request được giả lập nhưng lại là chạy tuần tự, nếu 15 request chạy đa luồng và song song nhau, chúng gọi GetLoadBalancer() gần như cùng thời điểm và _instance có thể đều chưa được khởi tạo giá trị và đều qua được chốt chặn if (_instance == null). Nếu như vậy có thể sẽ tạo ra 15 thể hiện khác nhau.
laptrinhvb.net via http://tek.eten.vn