1. Single Responsibility Principle (SRP) – Nguyên tắc trách nhiệm duy nhất
Mô tả: Một lớp chỉ nên có một lý do để thay đổi, nghĩa là nó chỉ nên có một nhiệm vụ duy nhất.
Lợi ích: Giúp hệ thống dễ bảo trì, giảm nguy cơ ảnh hưởng ngoài ý muốn khi thay đổi code.

Ví dụ sai lầm:
public class Report {
public void GenerateReport() { /* Code tạo báo cáo */ }
public void PrintReport() { /* Code in báo cáo */ }
}
Sửa đúng:
public class ReportGenerator {
public void GenerateReport() { /* Code tạo báo cáo */ }
}
public class ReportPrinter {
public void PrintReport() { /* Code in báo cáo */ }
}
2. Open/Closed Principle (OCP) – Nguyên tắc đóng/mở
Mô tả: Các module trong phần mềm nên được mở rộng mà không cần sửa đổi code hiện có.
Lợi ích: Giảm rủi ro bug khi thêm tính năng mới, dễ mở rộng hệ thống.

Ví dụ sai lầm:
public class AreaCalculator {
public double CalculateArea(Rectangle r) {
return r.Width * r.Height;
}
}
Sửa đúng:
public interface IShape {
double CalculateArea();
}
public class Rectangle : IShape {
public double Width, Height;
public double CalculateArea() => Width * Height;
}
public class Circle : IShape {
public double Radius;
public double CalculateArea() => Math.PI * Radius * Radius;
}public class AreaCalculator {
public double CalculateArea(IShape shape) {
return shape.CalculateArea();
}
}
3. Liskov Substitution Principle (LSP) – Nguyên tắc thay thế Liskov
Mô tả: Một lớp con phải có thể thay thế lớp cha của nó mà không làm thay đổi tính đúng đắn của chương trình.
Lợi ích: Đảm bảo tính kế thừa đúng đắn, tránh lỗi khi sử dụng đa hình.
Ví dụ sai lầm:
public class Bird {
public virtual void Fly() { Console.WriteLine(“Flying”); }
}
public class Penguin : Bird {
public override void Fly() { throw new Exception(“Penguins can’t fly!”); }
}
Sửa đúng:
public abstract class Bird {}
public interface IFlyable { void Fly(); }
public class Sparrow : Bird, IFlyable {
public void Fly() { Console.WriteLine(“Flying”); }
}
public class Penguin : Bird {}
4. Interface Segregation Principle (ISP) – Nguyên tắc phân tách Interface
Mô tả: Một interface lớn không nên ép các lớp con triển khai những phương thức mà chúng không sử dụng.
Lợi ích: Tránh việc các lớp không cần thiết phải implement những phương thức không dùng đến.
Ví dụ sai lầm:
public interface IWorker {
void Work();
void Eat();
}
Sửa đúng:
public interface IWorkable { void Work(); }
public interface IEatable { void Eat(); }
5. Dependency Inversion Principle (DIP) – Nguyên tắc đảo ngược sự phụ thuộc
Mô tả: Các module cấp cao không nên phụ thuộc vào các module cấp thấp. Cả hai nên phụ thuộc vào abstraction.
Lợi ích: Dễ thay đổi và mở rộng hệ thống mà không ảnh hưởng đến các phần khác.

Ví dụ sai lầm:
public class SQLDatabase {
public void SaveData(string data) { /* Lưu vào SQL */ }
}
public class DataService {
private SQLDatabase db = new SQLDatabase();
public void Save(string data) { db.SaveData(data); }
}
Sửa đúng:
public interface IDatabase {
void SaveData(string data);
}
public class SQLDatabase : IDatabase {
public void SaveData(string data) { /* Lưu vào SQL */ }
}
public class DataService {
private IDatabase _db;
public DataService(IDatabase db) { _db = db; }
public void Save(string data) { _db.SaveData(data); }
}