Composition over Inheritance (Ưu tiên thành phần hơn kế thừa)
Kế thừa thể hiện quan hệ “LÀ MỘT” (xe hơi là một phương tiện). Thành phần thể hiện quan hệ “CÓ MỘT” (xe hơi có một động cơ). Ưu tiên “có một”.
Vì sao kế thừa rủi ro khi app phình to
- Phải triển khai lại mọi phương thức trừu tượng của class cha, kể cả không cần.
- Rủi ro vi phạm Liskov Substitution Principle: class con hành vi xung đột class cha; ngược lại mọi thay đổi từ class cha có rủi ro gây lỗi tới các class con.
- Hệ thống phình to → nhiều luồng kế thừa song song (nghiệp vụ A: BaseClass A + đàn con; nghiệp vụ B: BaseClass B + đàn con…) → rất khó kiểm soát.
Cách áp dụng
Chia tách class/module thành các class con chịu trách nhiệm đơn lẻ, rồi kết hợp (compose) theo nhu cầu để tạo thành đối tượng mong muốn.
Ví dụ xuyên suốt sách: thân đèn + bóng đèn để riêng. Muốn đèn sáng màu gì, chỉ cần mua bóng tương ứng - dễ thay thế, linh hoạt. Đây chính là cách thực thi Composition over Inheritance thông qua Dependency Injection.
“Composition over Inheritance là nguyên tắc mà các lớp phải đạt được hành vi đa hình và tái sử dụng code bằng THÀNH PHẦN của chúng thay vì kế thừa từ lớp cơ sở.”
Liên quan
- Inheritance - Kế thừa - những rủi ro dẫn đến nguyên tắc này
- Dependency Injection - cách thực thi phổ biến nhất
- Strategy Pattern, Decorator Pattern - patterns dựa trên composition
- Single Responsibility Principle - chia nhỏ trước khi lắp ghép