SOLID – Bài 4: Interface Segregation Principle

List các bài đã viết:

Ở bài này ta sẽ tìm hiểu về nguyên tắc ứng với chữ I – chữ cái thứ tư trong SOLID – đó là Interface Segregation Principle (ISP). Tôi tạm dịch nguyên tắc này là “Tách Interface”. Nội dung của nguyên tắc này phát biểu như sau: “Các lớp thừa kế từ interface không nên bị ép buộc cài đặt những thứ nó không dùng đến từ interface đó”

Bạn có thể hiểu đơn giản thế này: “Lý do gì lại bán cái yên ngựa cho một gã không có ngựa?” (What is the point in selling a horse saddle for one who does not own a horse?).

Thực ra tôi định sẽ viết một số bài riêng về interface và abstract, delegate … nhưng vì tôi nhận ra điều đó hơi muộn, trong lúc viết cái series này, cho nên một số thứ các bạn tạm chấp nhận trước vậy (hoặc nếu bạn biết rồi thì càng tốt).

Interface giống như những ô cửa sổ. Bạn nhìn thế giới thông qua ô cửa sổ đó, và người ngoài kia nhìn vào nhà bạn cũng thông qua ô cửa sổ. Đứng ở ô cửa khác nhau, bạn thấy một góc mới của thế giới và người ở ngoài cũng vậy, nhìn vào ô cửa khác nhau, họ nhìn thấy những góc khác nhau của căn nhà của bạn. Việc gắn một cái cửa sổ vào nhà mình cũng là một việc cần suy nghĩ, vì chẳng ai gắn cả cái cửa sổ vào .. nhà vệ sinh cả hoặc vác cái cửa sổ quá to đến nỗi người ngoài nhìn thấy những góc mà bạn không muốn họ thấy.

Giả sử bạn gắn một cái cửa sổ không vừa với hơn cái tường nhà bạn, lúc đó sẽ có phần dư ra và trông sẽ rất dị hợm…

Sở dĩ tôi nói nhiều về “những cái cửa sổ” như vậy là để bạn hiểu tinh thần của nguyên tắc này. Đó là khi tạo ra một interface, nó cũng giống như việc lắp một cái cửa sổ vào nhà của bạn, bạn nên chọn cửa sổ vừa vặn với nhu cầu của bạn.

Ta xét ví dụ sau đây. Giả sử bạn xây dựng một module CMS (Content Management System). Hiện tại có 2 loại bài viết: Tin tức (News) và nghiên cứu (Research paper). Bạn định nghĩa một bài viết bằng interface IArticle và 2 class News và Paper cài đặt lại interface IArticle:

Sau một thời gian, giả sử bạn thấy rằng các bài viết về tin tức độc giả có nhu cầu đóng góp ý kiến trong khi đối với các bài viết nghiên cứu thì độc giả không cần ý kiến mà muốn có 1 phần link tham khảo. Do đó, bạn sửa chương trình bạn lại thành:

Ví dụ trên là một ví dụ điển hình cho việc vi phạm nguyên tắc này (ISP). Bạn có thể thấy các class News và Paper đều phải implement những thứ thừa thãi mà nó ko dùng đến. Như vậy, làm sao để giải quyết tình trạng này? Câu trả lời là bạn nên tách interface IArticle thành các interface khác nhỏ hơn và chuyên biệt hơn (lại nhắc tôi nhớ đến GeneralizationSpecification). Xin xem một cách giải quyết dưới đây:

Sau đó cài đặt lại các interface chuyên biệt này nay vì interface gốc:

Như vậy, bạn có thể thấy rằng bằng việc tách ra thành các interface chuyên biệt hơn, bạn đã tránh được việc phải implement những thứ không cần thiết trong chương trình của bạn. Một lợi điểm của phương pháp này nữa là nó giúp bạn đối phó với các mở rộng trong tương lai. Giả sử bạn cần thêm một loại tin tức mới là Advertising, tin tức này không cần comment mà cũng ko cần references, bạn có thể tạo class IAdvertisement cài đặt trực tiếp IArticle. Hoặc một loại tin tức gì đó mà có thể có cả comment và references ví dụ: ITutorial và ITutorial cài đặt cả ICommentedArticle và IReferencedArticle. Tôi không đưa code mẫu vì nghĩ không cần thiết, bạn có thể tự làm điều này dễ dàng.

Tóm lại, thực ra nguyên tắc này là một trường hợp đặc biệt của nguyên tắc LSP ở bài trước, mà nghĩ rộng ra cũng liên quan rất nhiều đến nguyên tắc còn lại đã học OCPSRP.

Enjoy coding!

No Comments

Post A Comment