Chuyển đến nội dung chính

Các nguyên lí cơ bản trong thiết kế hướng đối tượng

Bài này trích từ blog cntt.tv


Trong một thảo luận về kế thừa không hết ở JavaVietnam, người ta bàn về vấn đề thiết kế một pattern làm sao để lớp con kế thừa lớp cha nhưng tự loại bỏ những method mà nó không mong muốn. Điều đó có nghĩa là lớp con không tuân thủ "giao ước" (xin dùng từ của anh cl, ý chỉ contract) định trước, tức là nó không tuân thủ một trong những nguyên tắc cơ bản của thiết kế hướng đối tượng (OOD - Object oriented design) là Liscov substitution principle. Đ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à:
  1. Open closed
  2. Liskov substitution
  3. Dependency inversion
  4. Interface segregation
  5. 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ở đây.

Liskov substitution

Nguyên lí này được phát biểu như sau: FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.
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ở đây.

Dependency inversion

Việc áp dụng hai nguyên lí open-closedLiskov 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:
  1. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
  2. 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ỗ kiachỗ đó.

Interface segregation

Nguyên lí này được phát biểu như sau: CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE
Khi một client bị ép phải phụ thuộc vào những interface mà nó không sử dụng thì nó sẽ bị lệ thuộc vào những thay đổi của interface đó. Chúng ta cần phải tránh điều này nhiều nhất có thể bằng cách chia nhỏ interface.
Tham khảo thêm ở đây.

Single responsibility

Nguyên lí này được phát biểu như sau: THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.
Tham khảo thêm ở đâyở đây.
Chú ý: để hiểu bài này, cần có kiến thức cơ bản về lập trình hướng đối tượng, nhất là các khái niệm encapsulation, inheritance, polimorphism.

Nhận xét

  1. Bài viết này rất hay, ở trong trường ĐH, hầu hết đều dạy OOP nhưng dường như có vẻ sơ sài và đi nặng về hướng lập trình C++

    Trả lờiXóa
  2. Đúng vậy, nếu học ở trường thì OOP nghe chỉ như là mô phỏng đời thực vào lập trình thôi, và nhiều khi người ta áp dụng quá mức việc kế thừa trực tiếp. Những người giỏi lập trình thường là những người kế thừa interface hoặc abstract class nhiều hơn là kế thừa trực tiếp. Năm nguyên tắc đề cập ở bài này là năm nguyên tắc sống chết của người lập trình OOP, và dù biết áp dụng một cách hoàn chỉnh nó là không đơn giản, nhưng khi đã làm được, thì việc lập trình nhẹ như đi trên mây ^^.

    Trả lờiXóa
  3. The idea behind the SRP is that every class, module, or function in a program should have one responsibility/purpose in a program. As a commonly used definition, "every class should have only one reason to change". The class above violates the single responsibility principle.

    Trả lờiXóa

Đăng nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.