[vi] Kiến thức Adapter Pattern là gì? [series Design Pattern]

1. Adapter Pattern là gì?
Adapter Pattern is a structural design pattern that convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
Adapter Pattern là một Pattern thuộc nhóm Structural Pattern. Có vai trò như 1 class trung gian, Adapter giúp chuyển đổi interface của một class thành một interface khác mà hệ thống đang cần. Qua đó giúp class hoạt động được với hệ thống mặc dù không tương thích về interface.

Minh hoạ Adapter Pattern

Tương tự như ý nghĩa thực tế, Adapter như bộ chuyển giúp đầu cắm US tương thích với ổ cắm EU.​


2. Hiểu Adapter Pattern qua ví dụ thực tế
Cùng xem ví dụ thường gặp về Adapter Pattern trong lập trình OOP thực tế
Giả sử, Cty bạn có trang web bán hàng "Store" đang thanh toán credit card bằng một library/API/class thanh toán online "Paypal" do bên cty A cung cấp có interface như sau:
Adapter Pattern là gi?

Class Store của hệ thống cũ đang dùng Class CreditCardWithPayPal có interface PayPal để thanh toán​

Sếp bạn muốn chuyển qua dùng library/API/class thanh toán "Stripe" do cty B cung cấp với interface như sau:
Adapter Pattern là gì?

Class Store không tương thích với interface Stripe mới​

Ngặt nỗi code của bạn đã gọi method của library/API cty A "PayPal" rất nhiều nơi, sửa sẽ rất mệt. Vậy làm sao để không phải sửa lại code cũ nhưng vẫn dùng được class Stripe mới
Vậy giải pháp là Tạo 1 class Adapter chuyển interface của Stripe về tương tự với interface của PayPal. Rồi thay thế các Object PayPal được inject vào class Store thành Object của PayPalToStripeAdapter.
57

Store không đổi, Stripe không đổi. Tạo Class Adapter để tương thích interface cũ.​
Adapter hoạt động như người trung gian bằng cách nhận các yêu cầu từ client (hệ thống của bạn) và chuyển đổi chúng thành các yêu cầu có ý nghĩa đối với các lớp của nhà cung cấp mới.
Code sau khi thay đổi:
PHP:
// Không thay đổi. Bạn chỉ inject Adapter mới tạo vào __contruct thay vì object PayPal cũ
class Store
{
    private $paymentOnline;

    public function __construct(PayPal $paymentOnline) {
        $this->paymentOnline = $paymentOnline;
    }

    public function ThanhToanVaDatHang(int $soTien) {
        $this->paymentOnline->xemSoDu();
        $this->paymentOnline->thanhToan($soTien);
    }
}
PHP:
class PayPalToStripeAdapter implements PayPal
{
    private $creditCardWithStripe;

    public function __construct(Stripe $creditCardWithStripe) {
        $this->creditCardWithStripe = $creditCardWithStripe;
    }

    public function xemSoDu() {
        return $this->creditCardWithStripe->coiSoDu();
    }

    public function thanhToan(int $soTien) {
        return $this->creditCardWithStripe->traTien($soTien);
    }
}
PHP:
//Không thay đổi gì.
interface Stripe {
    public function coiSoDu();
    public function traTien(int $soTien);
}

class CreditCardWithStripe implements Stripe {
    public function coiSoDu() {
        echo "So du trong the la 10tr";
    }

    public function traTien(int $soTien) {
        echo "Ban da tra so tien $soTien";
    }
}
3. Các khái niệm trong Adapter Pattern
  • Client: Đây là lớp sẽ sử dụng đối tượng của bạn (hệ thống của chúng ta - "Store").
  • Target interface: Là interface của các đối tượng mà Client đang sử dụng ("")
  • 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 (hệ thống mới - "CreditCardWithStripe").
  • 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 ("PayPalToStripeAdapter").
*Lưu ý: Mỗi người sẽ có cách đặt tên Adapter khác nhau.
Tài liệu này sẽ quy định cách đặt tên là <Target_interface>To<Adaptee_interface>Adapter

56

UML mô tả tống quát về Adapter​
Ở đây, cách Client sử dụng Adapter:
  1. Client đưa ra yêu cầu cho adapter bằng cách gọi một phương thức trên nó.
  2. Adapter chuyển yêu cầu thành một hoặc nhiều cuộc gọi đến adaptee bằng adaptee interface.
  3. Client nhận được kết quả của cuộc gọi và không bao giờ biết có một Adapter đang thực hiện chuyển đổi.
Lưu ý rằng ClientAdaptee đã được tách rời – chúng không biết về nhau.

BÀI TẬP:
Giả sử chúng ta cũng cần một Adapter chuyển đổi PayPal thành Stripe (ví dụ lúc nãy là Stripe chuyển thành PayPal). Hãy gọi nó là PayPalToStripeAdapter. Hãy viết lớp đó.

Tham khảo:
Hướng dẫn Java Design Pattern – Adapter - GP Coder (Lập trình Java)
Chương 7: Adapter Pattern và Facade Pattern - Trở nên thích nghi (P1)
2.1. Adapter / Wrapper — DesignPatternsPHP 1.0 documentation
 
Last edited:

Facebook Comments

Top