Decorator Pattern in PHP cover image

Decorator Pattern in PHP

Sam Ciaramilaro • December 12, 2022

application-design

The decorator pattern is an object-oriented design pattern that allows developers to modify existing objects without changing their structure. It is used to add additional functionality to an object without having to modify the original code. This pattern is often used in web development to create complex applications with a lot of different features.

The decorator pattern is a great way to add extra functionality to an existing object without having to change the original code. This allows developers to quickly add new features to an existing object without having to go through the entire codebase. Additionally, the decorator pattern helps to keep code DRY (Don't Repeat Yourself) by avoiding the need for code duplication.

In this article, we will look at the decorator pattern and how it can be used in the context of a web shop. We will also provide an example in PHP to demonstrate how this pattern can be implemented.

What is the Decorator Pattern?

The decorator pattern is a structural design pattern that allows developers to modify the behavior of an object without changing its original structure. It is a powerful way to add extra functionality to an existing object without needing to modify the original code.

The decorator pattern is a type of wrapper or adapter that wraps an object and adds extra functionality to it. The decorator pattern uses composition instead of inheritance to extend the functionality of an existing object. This makes it possible to add multiple layers of functionality to an object without having to create a new class.

In the context of a web shop, the decorator pattern can be used to add extra features to a product. For example, a customer might want to add a special promotion or discount to a certain product. The decorator pattern can be used to add this additional feature without having to modify the original product code.

Example of the Decorator Pattern in a Web Shop

Let's take a look at how the decorator pattern can be used in the context of a web shop. As an example, we will create a class for a product and two decorator classes for promotions and discounts.

Product Class

First, we will create a class for a product. This class will contain the basic information about a product, such as its name and price.

class Product
{
    protected $name;
    protected $price;

    public function __construct($name, $price)
    {
        $this->name = $name;
        $this->price = $price;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getPrice()
    {
        return $this->price;
    }
}
Promotion Decorator

Next, we will create a decorator class for promotions. This class will take a product object as an argument and add a promotion discount to it.

class PromotionDecorator
{
    protected $product;

    public function __construct(Product $product)
    {
        $this->product = $product;
    }

    public function getName()
    {
        return $this->product->getName() . ' (Promotion)';
    }

    public function getPrice()
    {
        return $this->product->getPrice() * 0.9; // 10% discount
    }
}
Discount Decorator

Finally, we will create a decorator class for discounts. This class will take a product object as an argument and add a discount to it.

class DiscountDecorator
{
    protected $product;
    protected $discount;

    public function __construct(Product $product, $discount)
    {
        $this->product = $product;
        $this->discount = $discount;
    }

    public function getName()
    {
        return $this->product->getName() . ' (Discount)';
    }

    public function getPrice()
    {
        return $this->product->getPrice() * (1 - $this->discount);
    }
}

Using the Decorator Pattern

Now that we have created the classes for our product and the decorator classes for promotions and discounts, we can use the decorator pattern to add extra functionality to our product.

For example, we can create a new product with a promotion discount like this:

$product = new Product('iPad', 2000);
$discountDecorator = new DiscountDecorator($product, 0.2);

echo $discountDecorator->getName(); // iPad (Discount)
echo $discountDecorator->getPrice(); // 1600

Conclusion

The decorator pattern is a powerful tool for adding extra functionality to existing objects without having to modify the original code. In the context of a web shop, the decorator pattern can be used to quickly add extra features, such as promotions and discounts, to products.

The decorator pattern is a great way to keep code DRY by avoiding code duplication and allowing developers to quickly add extra features without having to go through the entire codebase. Additionally, the decorator pattern makes it easier to maintain and debug code, as all the functionality is contained within the decorator classes.

Overall, the decorator pattern is a great tool for creating complex applications with a lot of different features. It is a powerful way to extend the functionality of an existing object without changing its structure.