Adapter

Dẫn nhập thực tiễn:

Có một super dev triển khai code corebank trong ngân hàng, sau một thời gian anh ta đã tích hợp được thư viện thanh toán SmartLink với hệ thống core, tuy nhiên chỉ sau đó vài năm khi ngân hàng nhà nước bắt buộc phải tích hợp với Banknet. Mặc dù cả hai bộ thư viện từ hai mạng thanh toán đều thực hiện những công việc tương tự nhưng về chi tiết là khác nhau. Vậy cần một thứ gì đó kết nối giữa hệ thống cũ và hệ thống mới mà đảm bảo cho việc thay đổi code là ít nhất và hiệu suất nhất.

Hoặc:
Nguồn điện ở Việt Nam là 220V. Nguồn điện ở Nhật là 110V. Một ngày đẹp trời nọ, ông sếp người nhật qua Việt nam bàn thảo công việc. Bạn có nghĩ ông ấy vẫn tiếp tục cắm thiết bị để xài hay là không?
Nếu bạn chưa biết về thông tin trên tôi đoán là bạn cho là sẽ tiếp tục cắm. Nhưng nếu người có thông tin và hiểu biết về điện họ sẽ tìm cách để chuyển đổi nguồn điện cho phù hợp. Và thiết bị chuyển đổi điện có tên là adapter. Trong thực tế, bộ chuyển đổi (adapter) được sử dụng rất nhiều, ví dụ: bạn vẫn hay xem phim trên màn hình lớn TV bằng cách cắm dây HDMI từ máy laptop sang TV, một thời gian sau bạn chuyển từ chiếc laptop Dell cũ kỹ sang con MacBook Pro cực đẹp, nhưng tiếc thay nó không có cổng HDMI để cắm dây HDMI lên TV. Rất may là các chuyên gia trong lĩnh vực điện tử đã biết có vấn đề này và họ thiết kế bộ chuyển đổi từ DisplayPort sang HDMI, và bạn đã có thể truyền hình ảnh từ con MacBook lên TV để thưởng thức những bộ phim bom tấn.

1.jpg

Định nghĩa:

Do vấn đề tương thích, thay đổi interface của một lớp thành một interface khác phù hợp với yêu cầu người sử dụng lớp.
Tần suất sử dụng: cao trung bình 

UML class diagram

 

 

Trong đó:

  • Client: Đây là lớp sẽ sử dụng đối tượng của bạn (đối tượng mà bạn muốn chuyển đổi giao diện).
  • Adaptee: Đây là những lớp bạn muốn lớp Client sử dụng, nhưng hiện thời giao diện của nó không phù hợp.
  • Adapter: Đây là lớp trung gian, thực hiện việc chuyển đổi giao diện cho Adaptee và kết nối Adaptee với Client.
  • Target: định nghĩa giao diện Client đang làm việc (phương thức request()).

 

Phân loại adapter

Trong hướng đối tượng có hai khái niệm quan trọng song hành cùng nhau, đó là:

  • Composition: cấu thành. Nghĩa là một lớp B nào đó sẽ trở thành một thành phần của lớp A (một field trong lớp A). Tuy lớp A không kế thừa lại giao diện của lớp B nhưng nó có được mọi khả năng mà lớp B có.
  • Inheritance: kế thừa. Nghĩa là một lớp Derived sẽ kế thừa từ lớp Base và thừa hưởng tất cả những gì lớp Base có. Nhờ kế thừa mà nó giúp tăng khả năng sử dụng lại code, tăng khả năng bảo trì và nâng cấp chương trình. Và do vậy kế thừa là khái niệm trọng tâm trong hướng đối tượng. Nhưng nó có một nhược điểm, đôi khi nếu chúng ta quá lạm dụng nó, nó sẽ làm cho chương trình của chúng ta phức tạp lên nhiều, điển hình là trong lập trình game. Do vậy đôi lúc trong lập trình game người ta thường có khuynh hướng thích sử dụng composition hơn.

Và ứng với hai khái niệm này sẽ cho ta hai cách để chúng ta cài đặt lớp adapter: Object Adapter và Class Adapter.

Cách thực hiện

a) Tiếp hợp lớp (dùng thừa kế – inheritance) – Class Adapter Pattern

Trong mô hình tiếp hợp lớp, một lớp mới (Adapter) sẽ kế thừa lớp có sẵn với giao diện không tương thích (Adaptee), đồng thời cài đặt giao diện mà người dùng mong muốn (Target). Trong lớp mới, khi cài đặt các phương thức của giao diện người dùng mong muốn, phương thức này sẽ gọi các phương thức cần thiết mà nó thừa kế được từ lớp có giao diện không tương thích.

Tiếp hợp lớp đơn giản nhưng dễ gặp trường hợp đụng độ tên phương thức. Ví dụ:

2.PNG

3.PNG

4.PNG

5.PNG

6.PNG

b) Tiếp hợp đối tượng (dùng tích hợp – composition)  – Object Adapter Pattern

Đây là một phương pháp cài đặt Adapter Pattern dựa trên ý tưởng về composition. Một lớp mới (Adapter) sẽ tham chiếu đến một (hoặc nhiều) đối tượng của lớp có sẵn với giao diện không tương thích (Adaptee), đồng thời cài đặt giao diện mà người dùng mong muốn (Target). Trong lớp mới này, khi cài đặt các phương thức của giao diện người dùng mong muốn, sẽ gọi phương thức cần thiết thông qua đối tượng thuộc lớp có giao diện không tương thích. Tiếp hợp đối tượng tránh được vấn đề đa thừa kế, không có trong các ngôn ngữ hiện đại (Java, C#).

Tiếp hợp đối tượng tránh được vấn đề đa thừa kế, không có trong các ngôn ngữ hiện đại (Java, C#). Ví dụ:

7.PNG

8.PNG

9.PNG

Tùy theo cách tiếp hợp của đối tượng Adapter, ta có một số biến thể:

  • Pluggable Adapter: cho phép tiếp hợp động với vài lớp. Dĩ nhiên Adapter chỉ tiếp họp chỉ có thể tiếp hợp đến các lớp mà nó “nhận thấy”, thông thường Adapter sẽ quyết định lớp nào được tiếp hợp với Target dựa trên các phương thức constructor hoặc các phương thức thiết lập đối số…
  • Two-way Adapter: hỗ trợ cả hai giao diện Target và Adaptee. Nó cho phép một đối tượng Adapter xuất hiện như một đối tượng Target hoặc một đối tượng Adaptee.

 Các pattern liên quan

  • Bridge Pattern: có cấu trúc tương tự nhưng mục tiêu khác (tách một giao diện khỏi phần cài đặt).
  • Decorator Pattern: cung cấp thêm chức năng nhưng không làm thay đổi giao diện, ở đây một Adapter sẽ phối hợp hai đối tượng khác nhau.
  • Proxy Pattern: định nghĩa một giao diện đại diện cho các đối tượng khác mà không làm thay đổi giao diện của các đối tượng được đại diện, điều này thực hiện được nhờ các Adapter.

Lợi ích

Việc sử dụng Adapter Pattern đem lại các lợi ích sau:

  • Cho phép nhiều đối tượng có giao diện giao tiếp khác nhau có thể tương tác và giao tiếp với nhau.
  • Tăng khả năng sử dụng lại thư viện với giao diện không thay đổi do không có mã nguồn.

Trường hợp sử dụng

Người lập trình có thể dùng Adapter Pattern trong những trường hợp sau:

  • Người lập trình muốn sử dụng một lớp đã tồn tại trước đó nhưng giao diện sử dụng không phù hợp như mong muốn.
  • Khi muốn tạo ra những lớp có khả năng sử dụng lại, chúng phối hợp với các lớp không liên quan hay những lớp không thể đoán trước được và những lớp này không có những giao diện tương thích.
  • Cần phải có sự chuyển đổi giao diện từ nhiều nguồn khác nhau.
  • Khi giao diện mong muốn không phải là interface mà là một lớp trừu tượng hay muốn tiếp hợp nhiều đối tượng cùng một lúc.

Leave a comment