Design Pattern | Adapter Pattern

Tôi chắc chắn điều này giống như một tình huống quen thuộc. Bạn có một thiết bị mong đợi một loại đầu nối, nhưng bạn lại có một đầu nối khác. Do đó, nó không khớp, bạn không thể tạo kết nối đó. Vì vậy, bạn sẽ cần có một bộ chuyển đổi để có hiệu lực, nó là một thiết bị giúp biến đầu nối khác nhau thành một thiết bị trung tính mong đợi. Bộ điều hợp thường được sử dụng vì các nhà cung cấp khác nhau sẽ có những đầu nối khác nhau phát triển cho các thiết bị của họ.

Ví dụ, một đầu nối phổ biến cho thiết bị ngoại vi, như bàn phím, đã từng là PS2. Nhưng các máy tính giữa các năm 1990 bắt đầu chỉ hỗ trợ cổng USB, vì vậy, những người có bàn phím, PS2 cũ hơn cần một bộ chuyển đổi để sử dụng chúng với các máy tính mới. Bộ điều hợp này đã chuyển đổi cổng USB của máy tính thành một đầu nối mà bàn phím cũ của máy tính có thể cắm vào.

Hệ thống phần mềm cũng phải đối mặt với vấn đề tương thích tương tự. Thay vì có các đầu nối vật lý, các hệ thống sẽ có các giao diện phần mềm không tương thích. Điều đó có nghĩa là, đầu ra của hệ thống có thể không phù hợp với đầu vào dự kiến của một hệ thống khác. Bạn sẽ thấy rằng đây là một vấn đề tái diễn khi hệ thống có sẵn của bạn kết hợp các thư viện của bên thứ ba và cần được kết nối tới các hệ thống khác. Adapter Pattern sẽ giúp tạo điều kiện giao tiếp giữa hai hệ thống hiện có bằng cách cung cấp giao diện tương thích. Mẫu thiết kế  này bao gồm một số phần.


Class Client sẽ là một phần trong hệ thống của bạn muốn sử dụng thư viện của bên thứ ba, hoặc hệ thống bên ngoài. Adaptee là một lớp trong thư viện của bên thứ ba hoặc hệ thống bên ngoài sẽ được sử dụng. Class Adapter nằm giữa Client và Adaptee, nó sẽ thực hiện một Interface mà target là giao diện khách hàng sẽ sử dụng. Adapter chuyển đổi phù hợp với những gì Client đang mong đợi, Client gửi yêu cầu đến bộ điều hợp bằng Interface target, Adapter sau đó sẽ dịch yêu cầu thành một thông điệp mà người được điều chỉnh sẽ hiểu. Sau khi dịch xong, nó sẽ gửi yêu cầu dịch cho người được điều chỉnh.

Bây giờ, chúng ta hãy xem làm thế nào chúng ta có thể thực hiện The  Adapter Pattern trong một ví dụ cụ thể, trong ví dụ này, chúng ta có một WebClient có sẵn mà chúng ta muốn sử dụng để làm việc với một WebService khác. Một WebClient dự kiến sẽ gửi bất kỳ đối tượng nào vào vào Request nhưng dịch vụ chỉ hỗ trợ một đối tượng Json.


Chúng ta cần một bộ chuyển đổi để chuyển đổi yêu cầu của đối tượng của mình thành đối tượng Json.
Bước 1, thiết kế giao diện đích. Bạn tạo giao diện đích mà lớp Adapter của bạn sẽ triển khai để lớp Client của bạn có thể sử dụng.


Bước 2, thực hiện giao diện đích với lớp Adapter. Bộ điều hợp của bạn cung cấp các phương thức sẽ đưa đối tượng lớp Client  và chuyển đổi nó thành đối tượng Json. Điều này có nghĩa là bộ điều hợp có thể chuyển đổi bất kỳ instance của một lớp mà máy khách có thể tạo và gửi nó trong một request. Lớp bộ điều hợp cũng sử lý chuyển yêu cầu dịch sang bộ điều hợp. Lớp máy khách chỉ cần biết về giao diện đích của bộ điều hợp trong bước 1.


Bước 3, gửi yêu cầu từ máy khách đến bộ điều hợp bằng giao diện đích, WebClient chịu trách nhiệm thực hiện một số công việc để tạo thông điệp cho bạn. Vì quy trình làm việc bình thường của WebClient là trả lại đối tượng cho cho Client, bạn không cần muốn sửa đổi phương thức DoWork bởi vì nó có thể phá vỡ các phần khác trong hệ thống của bạn.




Thay vào đó, bạn nên cho phép WebClient thực hiện hành vi này như bình thường và sau đó, thêm một phương thức gửi tin nhắn nơi bạn có thể chuyển bất kỳ bộ Adapter nào, WebService và bất kỳ tin nhắn nào bạn muốn gửi. Trong chương trình chính của bạn có thể như ở trên, bạn cần khởi tạo WebAdapter, WebService, và WebClient. WebClient thỏa thuận với bộ điều hợp thông qua giao diện WebRequester để gửi yêu cầu.

Lưu ý rằng, WebClient của bạn không cần biết gì về WebService, như nhu cầu của nó đối với các đối tượng Json. Bộ Adapter được "ẩn dụ" khỏi máy khách bởi wrapping adapter class. Vì vậy, nếu hai giao diện không tương thích, tại sao chúng ta không thay đổi một hoặc thậm chí cả hai, để chúng có thể nói chuyện với nhau ??

Chà, nếu bạn đã chú ý đến ví dụ của chúng ta ngay từ đầu, chúng ta không cho thấy việc triển khai lớp WebService. Điều này là do nó có nghĩa là đại diện cho bên thứ ba hoặc hệ thống bên ngoài mà chúng ta có thể không có quyền truy cập trực tiếp. Nếu như chúng ta có quyền truy cập trực tiếp vào các thư viện hoặc hệ thống đó, thì không phải nói làm gì ..

Nhưng vậy thì tại sao chúng ta không thay đổi giao diện hệ thống ??

Có thể điều đó sẽ làm việc, nhưng nếu một hệ thống con đang sử dụng nó thì sao ? Thay đổi các giả định thế này có thể vô tình phá vỡ một phần khác của hệ thống chúng ta, hãy nhớ rằng, Adapter Pattern có nghĩa là bao bọc bộ điều hợp và hiển thị giao diện đích cho khách hàng, gián tiếp thay đổi giao diện của bộ điều hợp thành giao diện mà khách hàng mong đợi bằng cách thực hiện giao diện đích, gián tiếp dịch yêu cầu cảu khách hàng sang một người "thích nghi", và sử dụng lại các phần lớn của hê thống của bạn để giao tiếp đúng với các thư viện của bên thứ ba mới hoặc các hệ thống bên ngoài.

Chỉ vì một giao diện không phù hợp với những gì hệ thống của bạn mong đợi, không có nghĩa là hệ thống phải thay đổi. Adapter Pattern là một kỹ thuật giúp thu hẹp khoảng cách giữa hai giao diện không tương thích. Điều này sẽ giúp bạn tiếp tục sử dụng các hệ thống hiện có của mình và tích hợp các nguồn bên ngoài vào chúng.
Cảm ơn.

Nhận xét

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

Hiểu về Norm Regularization

Những thuật toán nền tảng trong lĩnh vực Trí tuệ nhân tạo (Artificial Intelligence I)