Mẫu thiết kế bộ điều hợp trong Java

Tram Ho

Giới thiệu

Trong bài viết này, mình sẽ giới thiệu về mẫu thiết kế adapter design pattern trong Java. Đây là một loại mẫu thiết kế cấu trúc (structural design patterns), cho phép 2 interfaces không liên quan, k có điểm chung làm việc cùng với nhau.
Mô hình này rất dễ hiểu vì thế giới thực có đầy đủ các adapter cho ta dễ hình dung. Ví dụ, hãy xem xét một bộ chuyển đổi USB sang Ethernet. Chúng ta cần điều này khi chúng ta có interface Ethernet ở một đầu và đầu kia là USB. Vì chúng không tương thích với nhau. chúng ta sử dụng một bộ chuyển đổi để chuyển đổi cái này sang cái khác. Ví dụ này khá giống với adapter hướng đối tượng. Trong thiết kế, các bộ điều hợp được sử dụng khi chúng ta có một lớp (Client) mong đợi một số loại đối tượng và chúng ta có một đối tượng (Adaptee) cung cấp các tính năng tương tự nhưng để lộ một giao diện khác.

Sử dụng adapter:

  • Client đưa ra yêu cầu cho adapter bằng cách gọi một phương thức trên nó bằng giao diện đích.
  • Adapter dịch yêu cầu đó trên adaptee bằng giao diện của adaptee.
  • Client nhận được kết quả của cuộc gọi và không biết về sự hiện diện của adapter.
    The adapter pattern chuyển đổi giao diện của một lớp thành một giao diện khác mà client mong đợi, nó cho phép các lớp làm việc cùng nhau mà các giao diện đó không tương thích với nhau.
    Cùng xem qua diagram để có 1 cái nhìn tổng quan về cấu trúc của mẫu thiết kế này:

    Client chỉ nhìn thấy giao diện đích chứ không phải adapter. The adapter thực hiện giao diện đích. Adapter ủy thác tất cả các yêu cầu cho Adaptee.

Ví dụ 1:

Giả sử bạn có một lớp Bird với các phương thức fly()makeSound(). Và cũng là một lớp ToyDuck với phương thức squeak(). Hãy giả sử rằng bạn thiếu các đối tượng ToyDuck và bạn muốn sử dụng các đối tượng Bird ở vị trí của chúng. Bird có một số chức năng tương tự nhưng thực hiện một giao diện khác, vì vậy chúng ta có thể sử dụng chúng trực tiếp. Vì vậy, chúng ta sẽ sử dụng mô hình adapter. Ở đây, client sẽ là ToyDuck và adaptee sẽ là Bird.
Dưới đây là source code của ví dụ:

Và đây là output của ví dụ:

Giải thích: Ở đây chúng ta đã tạo ra một lớp BirdAdapter implement inteface ToyDuck để chuyển đổi phương thức makeSound() của Bird thành phương thức squeak() của ToyDuck. Bằng cách này, ta vẫn có thể gọi được phương thức squeak() của các đối tượng Bird thông qua BirdAdapter
Before: ToyDuck toyDuck = new PlasticToyDuck();
After: ToyDuck toyDuck = new BirdAdapter(sparrow);
Bạn có thể thấy rằng bằng cách thay đổi chỉ một dòng, toyDuck giờ có thể thực hiện Chirp Chirp !!

Ví dụ 2

Ví dụ 1 bên trên là một ví dụ đơn giản để chúng ta có thể dễ hình dung về cách adapter nắm giữ một adaptee để thực hiện chuyển đổi và giao tiếp. Bây giờ cùng đến với ví dụ phức tạp hơn một chút:
Chúng ta có interface MediaPlayer và lớp AudioPlayer cụ thể implement MediaPlayer. AudioPlayer có thể phát các tệp âm thanh định dạng mp3 theo mặc định.
Chúng ta đang có một interface khác AdvancedMediaPlayer và các classes cụ thể implement interface AdvancedMediaPlayer. Các class này có thể phát các tệp định dạng vlc và mp4.
Chúng ta muốn tạo AudioPlayer để chơi các định dạng khác. Để đạt được điều này, chúng tôi đã tạo một class MediaAdapter, nó implements the MediaPlayer interface và sử dụng các đối tượng AdvancedMediaPlayer để chơi định dạng bắt buộc.
AudioPlayer sử dụng adapter của class MediaAdapter chuyển qua loại âm thanh mong muốn mà không cần biết class thực tế có thể phát định dạng mong muốn. AdapterPotypeDemo, class demo của chúng ta sẽ sử dụng class AudioPlayer để chơi các định dạng khác nhau.
Dưới đây là class diagram của ví dụ:

Sau đây là source code cho ví dụ này:

Output của ví dụ:

References:

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo