- vừa được xem lúc

SOLID - Interface Segregation (P1)

0 0 3

Người đăng: refacore

Theo Viblo Asia

Nguyên lý này có một phát biểu rõ ràng nhưng lại mù mờ trong cách hiểu và cách áp dụng. Bạn có đang thực sự áp dụng nguyên lý này trong công việc? Có một vài lý do. Trước tiên tôi muốn chúng ta làm rõ về cách tiếp cận.

Một class không thừa kế interface, nhưng thực thi interface

Mặc dù interface nằm trong danh sách thừa kế của một class, nhưng về bản chất, class không thừa kế thứ gì từ interface, vì interface hoàn toàn rỗng. Interface là phương tiện để mô tả hành vi (hay đặc trưng) của một class. Vì sao chúng ta cần interface? Hãy nhớ rằng C++ không có interface. Trong C# hay Java, một class chỉ được thừa kế một class khác nhưng có thể implement nhiều interface. Điều này khá rõ ràng trong Java khi có từ khóa inherits và implements riêng trong khi C# chỉ là một dãy class và interface sau dấu hai chấm.

Điều khác biệt giữa interface và class hay abstract class mà chúng ta có thể nhìn thấy, đó là interface mô tả những hành vi và những hành vi này có thể được chia sẻ trong cả hệ thống, không phải của riêng một họ class nào. Điều này liên quan đến cách để bạn có thể Segregate các interface. Dường như bạn phải thoát ra lối tư duy hướng đối tượng để có thể thiết kế các interface. Mở rộng tầm nhìn, loại bỏ các chi tiết thừa để tìm thấy các hành vi phổ biến trong hệ thống. Mặc dù các hành vi này là sự tương tác giữa các đối tượng, nhưng hãy tạm bỏ các đối tượng ra. Ví dụ thế này:

  • Bạn cần ghi log track các hành động trong hệ thống. Các thông tin cần thiết là CreatedDate và CreatedBy. Đây là một hành vi thậm chí là phổ quát cho mọi đối tượng.
  • Bạn tạo một interface IHasCreationInfo
  • Với mỗi hành động diễn ra, bạn kiểm tra "if cmd is IHasCreationInfo then logger.Write(cmd)". Bạn vốn không quan tâm tới đối tượng nào, chỉ quan tâm tới đặc trưng cụ thể.

Một câu hỏi đặt ra là nếu không có use case ghi log như trên, chúng ta có cần tạo ra interface IHasCreationInfo hay không?

Một ví dụ khác là trong gia đình có vợ chống, con cái và một con mèo. Chúng ta thấy rằng vợ chồng, con cái là các đối tượng có mối liên hệ về thừa kế, chia sẻ nhiều đặc trưng. Con mèo thì không liên quan gì cả. Nhưng cả gia đình chia sẻ nhiều hành vi chung như ăn, ngủ, đi, đứng. Khi chúng ta thực hiện hành động cho ăn, nếu không có interface, chúng ta cần hai phương thức FeedHuman(Human) và FeedKitty(Cat). FeedHuman rõ ràng có thể Feed Wife, Feed Husband, Feed Son, Feed Daughter. Wife, Husband, Son, Daughter đều có hành vi Eat thừa kế từ Human. Kitty cũng có hành vi Eat thừa kế từ Cat. Việc phân tách hành vi Eat ra interface IEatable giúp chúng ta đơn giản hóa việc cho ăn: Feed(IEatable). Sau này gia đình có nuôi thêm chó, vẹt, cá mây chiều thì phương thức Feed(IEatable) vẫn không thay đổi.

Hãy tưởng tượng class là các sợi chỉ ngang, interface interface là các sợi chỉ dọc, đan vào nhau và bạn có một tấm vải chắc chắn. Interface kết nối các class lại với nhau. Nếu interface chỉ được dùng cho một class và các dẫn xuất của nó thì khó mà nói nó phát huy hết sức mạnh. Chúng ta có nguyên tắc thứ 5 Dependency Inversion để nhấn mạnh việc trừu tượng hóa, thực tế là việc tạo các abstract class và các interface. Nhưng việc tạo ra IHuman với phương thức Eat và ICat với phương thức Eat của riêng nó chưa phát huy tối đa sức mạnh đúng không? Phân tách interface là thế, IHuman có phương thức Speak của Human, ICat có phương thức Meow của Cat, và IEatable mà abstract hay concrete class của IHuman, ICat đều implement. Phân tách không phải chỉ là chia nhỏ ra, mà chia có mục đích rõ ràng. Hãy ghi nhớ rằng chúng ta chỉ nên phân tách các hành vi được chia sẻ trong hệ thống. Speak là phương thức chỉ Human làm được, tách một interface ISpeakable chỉ làm chương trình thêm rối rắm. Các use case liên quan đến Speak chắc chắn liên quan đến Human, và sử dụng IHuman sẽ chứa nhiều ngữ nghĩa hơn ISpeakable.

Có những hành vị phụ thuộc vào một đối tượng nhưng cũng có những hành vị phụ thuộc vào một hành vi khác. Slogan của OOP là mọi thứ đều là đối tượng. Chúng ta có nên, qua interface coi một hành vi - đặc trưng - phương thức - thuộc tính cũng là một đối tượng? Tôi nghĩ như thế thì thật xoắn não. Hãy coi interface là một phương tiện giúp chúng ta nhìn các đối tượng ở một góc độ khác, là lưỡi dao để chúng ta khắc họa các class. Segregate interface có thể coi như là quá trình chúng ta khắc họa các mặt của một class, mặt nào riêng và mặt nào chia sẻ.

Bài sau, tôi sẽ bàn về các kiến trúc phần mềm hiện tại và có thể nó đã mài cùn kiến thức OOP của chúng ta ra sao.

Bình luận

Bài viết tương tự

- vừa được xem lúc

SOLID trong lập trình hướng đối tượng (P2)

Chào mọi người, trong bài viết trước mình đã giới thiệu 2/5 tính chất của SOLID, ở bài viết này mình sẽ giới thiệu 3 tính chất còn lại. Mọi người hãy chuẩn bị 1 tách cafe, 1 tâm hồn đẹp để đọc và thấm nhuần bài viết này nhé .

0 0 38

- vừa được xem lúc

SOLID trong lập trình hướng đối tượng (P1)

SOLID là tập hợp những nguyên tắc mà mỗi lập trình viên cần tuân theo khi thiết kế cấu trúc 1 class trong lập trình hướng đối tượng. SOLID bao gồm 5 tính chất, 5 tính chất này giúp chúng ta phần nào hiểu được sự cần thiết nhất định của design patterns và software architecture trong lập trình nói chu

0 0 35

- vừa được xem lúc

Nguyên lý S.O.L.I.D trong JavaScript (P3)

Ở bài này chúng ta cùng tìm hiểu về nguyên lý thứ 4 của SOLID, đó là Interface Segregation principle thông qua 2 mục:. . Nguyên lý Interface Segregation là gì . .

0 0 58

- vừa được xem lúc

Áp Dụng Nguyên Tắc SOLID Trong Lập Trình

Giới Thiệu. 1. SOLID là gì. SOLID là viết tắt của 5 chữ cái đầu trong 5 nguyên tắc:.

0 0 37

- vừa được xem lúc

Nguyên lý S.O.L.I.D. trong JavaScript (P4)

Hi mọi người, trong các bài viết trước chúng ta đã tìm hiểu về 4 nguyên lý đầu tiên của SOLID, trong bài viết này, chúng ta cùng tìm hiểu về chữ cái cuối cùng nhé. 1.

0 0 33

- vừa được xem lúc

Áp dụng SOLID trong Android

1. SOLID là gì. Thử tưởng tượng bạn đang ở trong một thư viện sách. Bạn muốn tìm một cuốn sách nào đó.

0 0 85