DESIGN PATTERN
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Bài 02: Design pattern PHP - Adapter Pattern

Tiếp tục serie Design pattern PHP thì trong bài này chúng ta tìm hiểu về Adapter Pattern. Loại pattern đặc biệt này khi chương trình phần mềm hoặc ứng dụng website của bạn có phụ thuộc vào các API từ bên ngoài hoặc là sử dụng một số lớp khác có sự thay đổi thường xuyên về tên hàm, tên lớp, ... Đây là một loại pattern thuộc nhóm mô hình cấu trúc (Structural patterns) bởi vì nó cho chúng ta cách code mở rộng và dễ quản lý code hơn.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Tại sao cần sử dụng Adapter pattern

Khi các bạn làm việc nhóm thì việc đặt ra quy tắc code là điều nên làm vì sẽ thống nhất hơn. Tuy nhiên trong thực tế đôi lúc sẽ có những thay đổi đột xuất và bạn sẽ mất cả khối thời gian để xử lý thay đổi đó, điều này thật nhàm chán. Để rõ hơn thì ta có một ví dụ dưới đây.

Giả sử xếp giao cho bạn một lớp dùng để xử lý thanh toán online Bảo Kim như sau:

class Baokim {

    public function __construct() {
        // Hàm khởi tạo
    }

    public function sendPayment($amount){
        // Code xử lý gửi thanh toán tại đây
    }
}

Cách sử dụng lớp này cũng tương đối đơn giản bạn chỉ cần tạo mới và sử dụng như sau:

Bài viết này được đăng tại [free tuts .net]

$baokim = new Baokim();
$baokim->sendPayment(1234);

Có một điều chắc chắn rằng trong ứng dụng của bạn sẽ phải sử dụng nhiều hơn một lần lớp này, như vậy ban sẽ phải tạo mới và gọi đến phương thức sendPayment() nhiều lần.

Bây giờ ta có tính huống như sau, sau khoảng thời gian 1 tuần, khi mà bạn đã gần như làm xong dự án và xếp bảo là lớp Baokim đã được chỉnh sửa lại tên của phương thức sendPayment() sang doPayment(). Ôi trời ơi, lúc này bạn sẽ phải quay lại code và sửa tất các các vị trí mà bạn đã sử dụng cheeky

Để giải quyết vấn đề này thì ta sử dụng kiểu Adapter Pattern. Ý tưởng của nó là khi có sự thay đổi của lớp khác (API)  đang sử dụng thì ta chỉ sửa đúng 1 chỗ thôi thay vì phải đi vào từng file để sửa. Và đây là các bước làm:

  • Coi lớp Baokim là một class gốc bên xếp gửi sang
  • Tạo ra một interface paymentAdapter
  • Tạo ra lớp baokimAdapter implements paymentAdapter

// Lớp gốc
class Baokim {

    public function __construct() {
        // Hàm khởi tạo
    }

    public function sendPayment($amount){
        // Code xử lý gửi thanh toán tại đây
        echo $amount;
    }
}

// Tạo một interface để các adapter không có quyền đổi tên hàm 
interface paymentAdapter{
    public function pay($amount);
}

// Lớp adapter sử dụng
class baokimAdapter implements paymentAdapter{
    private $__baokim;
    public function __construct(Baokim $baokim) {
        $this->__baokim = $baokim;
    }
    
    public function pay($amount){
        $this->__baokim->sendPayment($amount);
    }
}

// Cách dùng
$baokimAdapter = new baokimAdapter(new Baokim());
$baokimAdapter->pay(1234);

Như vậy mỗi khi sử dụng thì thay vì sử dụng lớp Baokim thì ta sử dụng baokimAdapter. Riêng paymentAdapter là một interface tạo ra nhằm mục đích không cho ta sửa tên hàm pay() (đọc bài template interface php).

Bây giờ xếp bảo lớp Baokim thay đổi phương thức sendPayment thành doPayment thì thay vì vào từng dòng code sửa thì ta chỉ cần sửa nó ở hàm pay() trong lớp baokimAdapter.

class baokimAdapter implements paymentAdapter{
    private $__baokim;
    public function __construct(Baokim $baokim) {
        $this->__baokim = $baokim;
    }
    
    public function pay($amount){
        $this->__baokim->doPayment($amount);
    }
}

2. Thêm một adapter khác

Giả sử ta có thêm một chức năng gửi tiền đặt phòng, xếp sẽ gửi qua một lớp như sau:

class Booker {

    public function __construct() {
        // Hàm khởi tạo
    }

    public function paymentRoom($amount){
        // Code xử lý gửi thanh toán tại đây
        echo $amount;
    }
}

Ok, ta tiếp tục làm như ví dụ trên như sau:

// Lớp gốc
class Booker {

    public function __construct() {
        // Hàm khởi tạo
    }

    public function paymentRoom($amount){
        // Code xử lý gửi thanh toán tại đây
        echo $amount;
    }
}

// Tạo một interface để các adapter không có quyền đổi tên hàm 
interface paymentAdapter{
    public function pay($amount);
}

// Lớp adapter sử dụng
class bookerAdapter implements paymentAdapter{
    private $__booker;
    public function __construct(Booker $booker) {
        $this->__booker = $booker;
    }
    
    public function pay($amount){
        $this->__booker->paymentRoom($amount);
    }
}

// Cách dùng
$bookerAdapter = new bookerAdapter(new Booker());
$bookerAdapter->pay(1234);

Như vậy ta sử dụng chung interface paymentAdapter cho cả hai trường hợp trên.

3. Lời kết

Adapter Design pattern thực sự rất hữu ích khi bạn code với ứng dụng lớn có sử dụng nhiều API từ bên ngoài, nó giúp bạn giảm thiểu tối đa nhưng thay đổi từ nhà cung cấp API. Nhìn thì thực sự nó hơi phức tạp vì phải tạo ra nhiều lớp và interface khác nhau nhưng nếu hệ thống lớn thì nó lại có rất nhiều hữu ích.

Cùng chuyên mục:

Hàm key_exists() trong PHP

Hàm key_exists() trong PHP

Cách sử dụng key_exists() trong PHP

Hàm mysqli_fetch_row() trong PHP

Hàm mysqli_fetch_row() trong PHP

Cách sử dụng mysqli_fetch_row() trong PHP

Hàm end() trong PHP

Hàm end() trong PHP

Cách sử dụng end() trong PHP

Hàm mysqli_field_count() trong PHP

Hàm mysqli_field_count() trong PHP

Cách sử dụng mysqli_field_count() trong PHP

Hàm count() trong PHP

Hàm count() trong PHP

Cách sử dụng count() trong PHP

Hàm mysqli_field_seek() trong PHP

Hàm mysqli_field_seek() trong PHP

Cách sử dụng mysqli_field_seek() trong PHP

Hàm compact() trong PHP

Hàm compact() trong PHP

Cách sử dụng compact() trong PHP

Hàm mysqli_field_tell() trong PHP

Hàm mysqli_field_tell() trong PHP

Cách sử dụng mysqli_field_tell() trong PHP

Hàm array_values() trong PHP

Hàm array_values() trong PHP

Cách sử dụng array_values() trong PHP

Hàm mysqli_free_result() trong PHP

Hàm mysqli_free_result() trong PHP

Cách sử dụng mysqli_free_result() trong PHP

Hàm array_unshift() trong PHP

Hàm array_unshift() trong PHP

Cách sử dụng array_unshift() trong PHP

Hàm mysqli_get_charset() trong PHP

Hàm mysqli_get_charset() trong PHP

Cách sử dụng mysqli_get_charset() trong PHP

Hàm array_shift() trong PHP

Hàm array_shift() trong PHP

Cách sử dụng array_shift() trong PHP

Hàm mysqli_get_client_stats() trong PHP

Hàm mysqli_get_client_stats() trong PHP

Cách sử dụng mysqli_get_client_stats() trong PHP

Hàm array_unique() trong PHP

Hàm array_unique() trong PHP

Cách sử dụng array_unique() trong PHP

Hàm mysqli_get_client_version() trong PHP

Hàm mysqli_get_client_version() trong PHP

Cách sử dụng mysqli_get_client_version() trong PHP

Hàm array_uintesect() trong PHP

Hàm array_uintesect() trong PHP

Cách sử dụng array_uintesect() trong PHP

Hàm mysqli_get_connection_stats() trong PHP

Hàm mysqli_get_connection_stats() trong PHP

Cách sử dụng mysqli_get_connection_stats() trong PHP

Hàm array_sum() trong PHP

Hàm array_sum() trong PHP

Cách sử dụng array_sum() trong PHP

Hàm mysqli_get_host_info() trong PHP

Hàm mysqli_get_host_info() trong PHP

Cách sử dụng mysqli_get_host_info() trong PHP

Top