Nguyên lý SOLID trong lập trình hướng đối tượng – và ví dụ sử dụng C# – p1 – Người thích tự do và lang thang như gió

 

Trong bài viết này chúng ta sẽ tìm hiểu về kiến trúc,  nguyên lý SOLID trong lập trình hướng đối tượng qua các ví dụ được viết bằng C#

Nội dung

Giới thiệu

Hiểu một cách đơn giản SOLID là 5 nguyên lý giúp lập trình viên phát triền phần mềm với kiến trúc tốt (mà tốt để làm gì thì mọi người đều hiểu rồi ha). SOLID bao gồm 5 nguyên lý sau:

  • S đại diện cho SRP (Single responsibility principle
  • O đại diện cho OCP (Open closed principle)
  • L đại diện cho LSP (Liskov substitution principle)
  • I đại diện cho ISP ( Interface segregation principle)
  • D đại diện cho DIP ( Dependency inversion principle)

Bây giờ chúng ta sẽ bắt đầu tìm hiểu các nguyên lý này qua từng ví dụ.

Tìm hiểu về “S”- SRP (Single responsibility principle)
Cách đơn giản nhất để tìm hiểu về SOLID là tìm hiểu về vấn đề mà nó đang giải quyết.

Hãy xem đoạn code bên dưới, bạn có thể đoán được nó đang cố gắng giải quyết vấn đề gì không? (Tất nhiên bạn không cần 1 cốc Bia để đoán – trông nó khá đơn giản mà phải không)

Ok, cùng xem đoạn code mẫu:

[enlighter lang=”CSharp”]
class Customer
{
public void Add()
{
try
{
// Database code goes here
}
catch (Exception ex)
{
System.IO.File.WriteAllText(@”c:\Error.txt”, ex.ToString());
}
}
}
[/enlighter]

Gượm đã chúng ta đang làm cái quái gì ở class Customer trên nhỉ? Hình như còn có cả ghi log file nữa.

Rõ ràng lớp Customer chỉ nên làm những việc như là validations dữ liệu, xử lý logic liên quan tới các dữ liệu của Customer thôi chứ, nhưng mà xem nào đoạn code trong catch đang làm việc với LOG!!!. Điều này sẽ gây ra khó khăn khi chúng ta muốn thay đổi lớp ghi log này. Mỗi lần muốn thay đổi cách thức ghi log file chúng ta lại vào lớp Customer để sửa. Thật mâu thuẫn!!!

Nguyên lý SRP phát biểu rằng: mỗi lớp chỉ nên làm duy nhất một nhiệm vụ (not multiple – :D). Vậy nên chúng ta sẽ chuyển đoạn code ghi log sang một class khác và lớp đó chỉ làm việc với Log.
Every software module should have only one reason to change

[enlighter lang=”CSharp”]
class FileLogger
{
public void Handle(string error)
{
System.IO.File.WriteAllText(@”c:\Error.txt”, error);
}
}
[/enlighter]
Giờ thì lớp Customer sẽ trông đơn giản hơn như thế này
[enlighter lang=”CSharp”]
class Customer
{
private FileLogger obj = new FileLogger();
publicvirtual void Add()
{
try
{
// Database code goes here
}
catch (Exception ex)
{
obj.Handle(ex.ToString());
}
}
}
[/enlighter]

 

Rồi đó, giờ thì mọi thứ đã rõ ràng. Class Customer chỉ làm việc với các đối tượng Customer và class FileLogger sẽ chuyên tâm làm việc với nhiệm vụ ghi log. Ở đây có thể dễ dàng thấy được lợi ích của việc tách 2 lớp này ra.  Để rõ thêm về lợi ích này. Các bạn có thể xem thêm phần 2 bài viết về SOLID với nguyên lý Open Close

Phần 2: Open-Close