Example 1

Imagine we have the following system when we want to add a product into the cart - never mind the implementations.

<?php

$productId = 12;

$cart = new Cart();

$product = new Product($productId);

if ( $product->getStock() > 0 ) {
    if ( $cart->addProduct($product) ) {
        echo "Product with ID $productId added to the cart". PHP_EOL;
    } else {
        echo "Something went wrong". PHP_EOL;
    }
} else {
    echo "Product with ID $productId is out of stock". PHP_EOL;
}

As you can see even if the example is a very simple one there is quite a process we need to code down when we want to add a product to the cart. Of course we would like to add a product into the cart from various places in our app. Writing the piece of code every time is extremely error prone because at some point we may need to  modify the add to cart process so we will need to modify the code at every file we have that logic.

In order to solve this problem we need to use a Facade class which will hide all the code given us a simple to use API to interact with.

<?php

class AddToCartFacade
{
    /**
     * @var int
     */
    private $productId;

    /*
     * @var Cart
     */
    private $cart;

    /*
     * @var Product
     */
    private $product;

    public function __construct()
    {
    }

    public function addProduct(int $productId)
    {
        $this->createCart();

        $this->createProduct($productId);

        if ( $this->product->getStock() < 0 ) {
            return "Product with ID $productId is out of stock". PHP_EOL;
        }

        if (! $this->cart->addProduct($this->product) ) {
            return "Something went wrong". PHP_EOL;
        }

        return "Product with ID $productId added to the cart". PHP_EOL;
    }

    private function createCart()
    {
        $this->cart = new Cart();
    }

    private function createProduct($productId)
    {
        $this->product = new Product($productId);
    }
}

And the calling code is 

<?php

$productId = 12;

//$cart = new Cart();
//
//$product = new Product($productId);
//
//if ( $product->getStock() > 0 ) {
//    if ( $cart->addProduct($product) ) {
//        echo "Product with ID $productId added to the cart". PHP_EOL;
//    } else {
//        echo "Something went wrong". PHP_EOL;
//    }
//} else {
//    echo "Product with ID $productId is out of stock". PHP_EOL;
//}


$addToCart = new AddToCartFacade();

echo $addToCart->addProduct($productId);