Open/Closed Principle (OCP): Các thực thể phần mềm (class, module, function) nên mở cho việc mở rộng (extension) nhưng đóng cho việc sửa đổi (modification).
Ví dụ vi phạm OCP
Lớp AreaCalculator phải sửa đổi mỗi khi thêm hình mới (Rectangle, Circle, Triangle...).
// TRƯỚC: Vi phạm OCP
public class Rectangle { public int Width { get; set; } public int Height { get; set; } }
public class Circle { public double Radius { get; set; } }
public class AreaCalculator
{
public double TotalArea(object[] shapes)
{
double area = 0;
foreach (var shape in shapes)
{
if (shape is Rectangle r) area += r.Width * r.Height;
else if (shape is Circle c) area += c.Radius * c.Radius * Math.PI;
// Thêm Triangle? Phải sửa class này!
}
return area;
}
}
Tuân thủ OCP: Dùng Abstraction (Interface/Abstract class)
// SAU: Tuân thủ OCP
public abstract class Shape
{
public abstract double Area();
}
public class Rectangle : Shape
{
public int Width { get; set; }
public int Height { get; set; }
public override double Area() => Width * Height;
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area() => Radius * Radius * Math.PI;
}
// Mới: Triangle không cần sửa AreaCalculator
public class Triangle : Shape
{
public double Base { get; set; }
public double Height { get; set; }
public override double Area() => 0.5 * Base * Height;
}
public class AreaCalculator
{
public double TotalArea(Shape[] shapes)
{
double area = 0;
foreach (var shape in shapes)
area += shape.Area(); // Polymorphism
return area;
}
}
Lợi ích
- Không sửa code cũ: Thêm hình mới chỉ cần tạo class kế thừa
Shape. - Giảm rủi ro: Code hiện có không bị thay đổi -> ít bug regression.
- Dễ test: Mỗi shape test độc lập.
- Tuân thủ SRP: Mỗi class chỉ lo việc tính diện tích của mình.
Các kỹ thuật mở rộng khác
- Strategy Pattern: Tách algorithm thành các class riêng.
- Decorator Pattern: Thêm hành vi mà không sửa class gốc.
- Plugin/Module system: Nạp assembly động.
- Delegate/Func: Truyền logic như parameter.
Lưu ý: OCP không có nghĩa là không bao giờ sửa code. Sửa lỗi (bug fix) vẫn cần thiết. OCP áp dụng cho việc thêm tính năng mới.