Design Patterns: The Facade Parttern

Design Patterns: The Facade Parttern##

Tại sao chúng ta nên sử dụng design patterns trong lập trình ?
Code của chúng ta có thể làm việc hiệu quả mà không có nó được không ?

Để trả lời câu hỏi trên chúng ta đặt ra câu hỏi như sau: "Bạn muốn sống trong một ngôi nhà sang trọng hay một ngôi nhà đơn giản với bốn bức tường". Cả hai tùy thuộc vào mục đích của bạn.

Thông thường, chúng ta tìm đến một ngôi nhà sang trọng bởi vì nó cho chúng ta mọi thứ và ít phải sửa chữa và ít gặp phải rắc rồi vì đã có nền tảng tốt.

Áp dụng những suy nghĩ đó sang lập trình: Code theo design patterns sẽ rất dễ dàng để hiểu, bảo trì và mở rộng.

Thực tế, có một vài design patterns khác nhau cho các bạn sử dụng. Design được chia theo các loại sau:

  • creational patterns
  • structural patterns
  • behavioral patterns
  • concurrency patterns

Trong bài viết này, chúng ta sẽ tìm hiểu về facade design pattern. Nó thuộc loại parttern về cấu trúc(structural patterns) bởi vì nó giúp cấu trúc code của bạn trở nên dễ dàng để bảo trì trong tương lai hơn. Bài viết sẽ sử dụng ngôn ngữ PHP để giải thích desgin pattern. Tuy nhiên, nguyên lý này có thể áp dụng với bất kỳ ngôn ngữ nào khác - nó chỉ thay đổi tùy thuộc vào cú pháp của ngôn ngữ.

Facade Design Pattern###

UML####

facade_design_pattern.jpg

Vấn Đề####

Giả sử bạn có một số thao tác cần thực hiện theo thứ tự và một vài action được yêu cầu thực hiện ở một vài chỗ trong ứng dụng của bạn. Do đó bạn sẽ phải lặp code ở một vài vị trí khác nhau. Sau một thời gian, bạn cần thay đổi code. Lúc này chúng ta cần thay đổi ở nhiều chỗ với cùng một nội dung. Như vậy sẽ rất phiền phức nếu ứng dụng của chúng ta ngày càng lớn và mở rộng.

Bài viết này sẽ giới thiệu cho các bạn việc thay đổi ở tất cả các vị trí trong một lần.

Giải Pháp####

Giải pháp được đưa ra ở đây là chúng ta tạo 1 controller để xử lý tất cả những phần lặp code. Bây giờ, nếu chúng ta cần thay đổi bất kỳ gì thì sẽ chỉ cần thay đổi trong controller và contoller sẽ áp dụng thay đổi lên tất cả các vị trí được sử dụng.

Ví Dụ###

Trong bài viết này, chúng ta sẽ nói về 1 ví dụ phổ biến của các trang web thương mại điện tử. Chúng ta sẽ cài đặt facade design pattern cho việc mua một sản phẩm. Nhưng trước khi áp dụng design pattern chúng ta cùng nhìn một số vấn đề của code.

Quy trình mua một sản phẩm gồm những bước sau:

  • Thêm sản phẩm vào giỏ hàng
  • Tính toán chi phí vận chuyển
  • Tính toán chi phí giảm giá
  • Sinh ra hóa đơn

Vấn đề####

// Simple CheckOut Process
$productID = $_GET['productId'];

$qtyCheck = new productQty();

if($qtyCheck->checkQty($productID) > 0) {

    // Add Product to Cart
    $addToCart = new addToCart($productID);

    // Calculate Shipping Charge
    $shipping = new shippingCharge();
    $shipping->updateCharge();

    // Calculate Discount Based on
    $discount = new discount();
    $discount->applyDiscount();

    $order = new order();
    $order->generateOrder();
}

Trong đoạn code trên, chúng ta thấy có một vài object cần cho việc hoàn thành việc mua một sản phẩm. Thử tưởng tượng rằng bạn cài đặt quy trình này ở nhiều địa điểm khác nhau. Nếu trong trường hợp có vấn đề phát sinh và code cần phải chỉnh sửa. Chúng ta cần phải lặp lại thay đổi ở nhiều địa điểm khác nhau.

Giải pháp####

Chúng ta sẽ viết tất cả những phần lặp lại vào facade pattern, sẽ làm code trở nên dễ dàng bảo trì và mở rộng hơn.

class productOrderFacade {

    public $productID = '';

    public function __construct($pID) {
        $this->productID = $pID;
    }

    public function generateOrder() {

        if($this->qtyCheck()) {

            // Add Product to Cart
            $this->addToCart();

            // Calculate Shipping Charge
            $this->calulateShipping();

            // Calculate Discount if any
            $this->applyDiscount();

            // Place and confirm Order
            $this->placeOrder();

        }

    }

    private function addToCart () {
        /* .. add product to cart ..  */
    }

    private function qtyCheck() {

        $qty = 'get product quantity from database';

        if($qty > 0) {
            return true;
        } else {
            return true;
        }
    }

    private function calulateShipping() {
        $shipping = new shippingCharge();
        $shipping->calculateCharge();
    }

    private function applyDiscount() {
        $discount = new discount();
        $discount->applyDiscount();
    }

    private function placeOrder() {
        $order = new order();
        $order->generateOrder();
    }
}

Bây giờ, chúng ta đã áp dụng facade design. Do đó thay vì phải gọi nhiều câu lệnh xử lý mua sản phẩm ở nhiều nơi thì chúng ta chỉ cần gọi như sau:

// Note: We should not use direct get values for Database queries to prevent SQL injection
$productID = $_GET['productId'];

// Just 2 lines of code in all places, instead of a lengthy process everywhere
$order = new productOrderFacade($productID);
$order->generateOrder();

Và bây giờ nếu phải thay đổi bạn chỉ cần đơn giản là thay đổi ở trong class facade.


All Rights Reserved