Thứ Tư, 16 tháng 1, 2013

Nguyên lý đơn nhiệm

1. Định nghĩa

Nguyên lý đơn nhiệm phát biểu như sau:

Một lớp nên có một lý do để thay đổi.

2. Giải thích

Đây là một nguyên lý đơn giản trong cách hiểu nhưng rất khó để áp dụng một cách chính xác trong thực tiễn.

Một lớp nên có một lý do để thay đổi.

Theo phát biểu trên, thì mỗi lớp chỉ nên hướng tới việc thực thi một nhiệm vụ. Thế nào là một nhiệm vụ?

Đây là một câu hỏi mang tính tương đối, vì trong nhiều tình huống, nhiệm vụ có thể bao gồm các hành vi tương hỗ, hoặc mang tính chất nhóm giống nhau chứ không nhất thiết chỉ là 1 hành vi.

Nội dung lớp thay đổi khi và chỉ khi nhiệm vụ của lớp đó thay đổi.

Chúng ta sẽ lấy ví dụ về chức năng của một cái điện thoại. Như chúng ta đã biết, điện thoại có những tính năng chính như sau: quay số, nghe, gọi. Đây là 3 tính năng cơ bản nhất mà bất kỳ điện thoại nào cũng phải có. Thế tại sao chúng ta không đưa vào các tính năng như chụp ảnh, quay phim, lưu trữ, chơi nhạc, game,....? Chúng ta không thể đưa những tính năng phụ trội vào điện thoại vì khi đó nó sẽ làm mất đi bản sắc gốc của một cái điện thoại, thay vào đó, chúng ta sẽ tạo các class kế thừa class điện thoại và tạo nên các kiểu mẫu điện thoại mới có thêm các tính năng phụ trội (cách này được dùng trong decorator pattern với mục đích là thêm vào các tính năng cho mẫu thiết kế).

Thế tại sao chúng ta phải quy định mỗi lớp chỉ thực hiện duy nhất một nhiệm vụ?
Thật ra việc quy định nhiệm vụ đặc trưng cho từng lớp trong thiết kế phần mềm nhằm đảm bảo sự nhất quán và tránh sự phực tạp khi có yêu cầu thay đổi tính năng xảy ra. Bạn hãy tưởng tượng nếu một class thực hiện quá nhiều tác vụ có liên quan lẫn nhau, sau đó các tác vụ này lại tham gia xử lý trong một tác vụ khác ở một lớp khác. Khi đó, sẽ có hiện tượng kết dính (couple) giữa các tác vụ. Hiện tượng này sẽ gây ra một số vấn đề tiêu cực sau:
- Đối với các ngôn ngữ có định nghĩa kiểu dữ liệu mạnh như C++, bộ biên dịch sẽ dịch các class để đảm bảo tính đúng đắn của kiểu dữ liệu. Theo đó, khi có sửa đổi ở một class có nhiều hiện tượng kết dính hoặc phụ thuộc với các class khác, nó sẽ biên dịch lại các class liên quan, điều này vô hình tạo ra các hành vi và kết quả không mong muốn trong một hệ thống đang được vận hành. Tệ hơn là bộ biên dịch có thể từ chối không biên dịch vì có thể xung đột với những giới hạn đặt ra trong quá trình chỉnh sửa (việc chỉnh sửa A vi phạm những giới hạn mà B đã quy định)
- Khó tách biệt các nhóm class phục vụ cho việc kiểm tra vì chúng phụ thuộc chồng chéo lẫn nhau. Do đó việc xác định lỗi sẽ rất khó khăn và tốn nhiều tài nguyên.
- Ứng dụng rất khó bảo trì. Việc thay đổi sẽ dẫn đến việc tìm hiểu lại các chức năng của class, khi đó sẽ rất khó xác định class nào thực hiện chức năng nào vì có quá nhiều nhiệm vụ được đặt vào trong 1 class.

3. Ví dụ


Không có nhận xét nào:

Đăng nhận xét