Điều đó cho thấy khi thiết kế, tìm giải pháp cho một vấn đề nào đó, việc nắm rõ các nguyên lí cơ bản của OOD là vô cùng quan trọng. Bài này xin giới thiệu về 5 nguyên tắc cơ bản của OOD là:
- Open closed
- Liskov substitution
- Dependency inversion
- Interface segregation
- Single responsibility
Open closed
Ivar Jacobson từng nói: “Để thiết kế các hệ thống lâu dài, cần luôn tâm niệm rằng các hệ thống luôn thay đổi trong quá trình sử dụng”. (All systems change during their life cycles. This must be borne in mind when developing systems expected to last longer than the first version.”). Năm 1988, Bertrand Meyer đưa ra mục tiêu để thực hiện điều mà Ivar Jacobson nói trên mà sau này trở thành nguyên lí open-closed nổi tiếng. Đó là: SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.
Các chương trình áp dụng nguyên lí open-close được thay đổi bằng cách thêm code mới chứ không phải sửa code có sẵn. Bằng cách này, tránh được thay đổi dây chuyền trong toàn bộ chương trình. Tuy nhiên, mỗi entity của chương trình có thể đóng với thay đổi này nhưng lại không đóng với thay đổi nào đó khác. Do đó, tính đóng này chỉ là tương đối và nhiệm vụ của người thiết kế là với mỗi đặc thù của chương trình, ưu tiên đóng các thuộc tính dễ thay đổi nhất.
Để “đóng” các entity của chương trình, có thể sử dụng giải pháp abstraction, data driven, ..
Open-closed là nguyên li trung tâm, rất quan trọng trong thiết kế hướng đối tượng vì chính nguyên lí này làm cho lập trình hướng đối tượng có tính tái sử dụng (reusability) và dễ bảo trì (maintainability).
Tham khảo thêm ở đây và ở đây.
Liskov substitution
Nguyên lí này được phát biểu như sau:
Tức là hoạt động của các function có sử dụng reference hay pointer tới object của lớp cha cần được đảm bảo là không bị ảnh hưởng khi thay thế reference hay pointer tới object của lớp cha bởi reference hay pointer tới object của lớp con và function đó không cần biết về sự tồn tại của lớp con. Khi đó, các virtual member functions ở lớp cha cũng phải có ở lớp con, và phải thực hiện một công việc có nghĩa.
Nếu nguyên lí này bị vi phạm, function có sử dụng reference hay pointer tới object của lớp cha phải kiểm tra kiểu của object để đảm bảo chương trình có thể chạy đúng, và việc này vi phạm nguyên lí open-closed nhắc đến ở trên.
Tham khảo thêm ở đây và ở đây.
Dependency inversion
Việc áp dụng hai nguyên lí open-closed và Liskov substitute một cách chặt chẽ có thể tổng quát hóa thành nguyên lí depndency inversion được phát biểu như sau:
- HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
- ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTION.
Thực hiện một bằng cách dùng abstract layer như hình dưới.
Tham khảo thêm ở chỗ này, chỗ kia và chỗ đó.
Interface segregation
Nguyên lí này được phát biểu như sau:
Tham khảo thêm ở đây.
Single responsibility
Nguyên lí này được phát biểu như sau: