Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to implement (understand) the Decorator pattern in php

I'm trying to understand the Decorator pattern and I have read other related questions on SO, then I decided to try it with a trivial example (I'm a PHP novice):

interface iTitle {
   public function getTitle();
}

class Title implements iTitle {
   protected $_text;

   public function __construct() {
      $this->_text='Our page';
   }

   public function getTitle() {
      return $this->_text;
   }
}

abstract class TitleDecorator implements iTitle {
   protected $_title;

   public function __construct(iTitle $title) {
      $this->_title=$title;
   }
}

class BeforeTitle extends TitleDecorator {
   public function getTitle() {
      return 'Welcome to '.$this->_title->getTitle();
   }
}

class AfterTitle extends TitleDecorator {
   public function getTitle() {
      return $this->_title->getTitle().', Dear user!';
   }
}

Is this a (kind of) right implementation of the Decorator pattern? If no, what would be the right way? If yes, could this be improved and how? Or maybe this would be more suitable for another pattern?

Any help/ideas would be appreciated, thanks in advance !

like image 260
Shaz Avatar asked Jun 15 '11 15:06

Shaz


People also ask

Is Python decorators are an implementation of the decorator pattern?

The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class, provided some groundwork is done at design time. Decorators in Python - Despite the name, Python decorators are not an implementation of the decorator pattern.

What is a Decorator in PHP?

Decorator is a structural pattern that allows adding new behaviors to objects dynamically by placing them inside special wrapper objects, called decorators. Using decorators you can wrap objects countless number of times since both target objects and decorators follow the same interface.

What is Decorator design pattern example?

The decorator design pattern is a structural pattern, which provides a wrapper to the existing class. Decorator design pattern uses abstract classes or interfaces with the composition to implement the wrapper.

What is the decorator pattern used for?

The Decorator Pattern allows class behavior to the decorated dynamically. It's a structural design pattern as it's used to form large object structures across many disparate objects. The concept of decorator is that it adds additional attributes to an object dynamically.


1 Answers

Is this a (kind of) right implementation of the Decorator pattern?

Yes

If yes, could this be improved and how? Or maybe this would be more suitable for another pattern?

Well you implemented the Decorator Pattern. I can not imagine what can be a better pattern than the decorator pattern when you want to implement one.

Normally one would use the Decorator to implement an interface and to replace only a fraction of the originals object and pass the rest along. That heavily depends on object usage. As your code shows only how to implement the pattern but not the use of the objects, it can not be specifically answered if or not that pattern fits your needs.

So you can implement other patterns as well and then decide on which one feels better. The crux with patterns is: Only if you know which exists, you can make use of them.

So next to patterns and the decision which one to choose there often is OOAD. If you're new to this, checkout this nice book.

About your code

I first answered yes when you asked about if that is right or not. Kind of it's right, but this part does looks wrong to me on a second sight:

class BeforeTitle extends TitleDecorator {
   public function getTitle() {
      return 'Welcome to '.$this->getTitle();
   }
}

It's wrong because the getter in the class BeforeTitle calls itself recursively (it calls itself again and again and again ...). I think that's not intended by you.

You do it correct in the other decorator class, referring to $this->_title which is the object instance that gets decorated:

class AfterTitle extends TitleDecorator {
   public function getTitle() {
      return $this->_title->getTitle().', Dear user!';
   }
}

You can use the Decorator pattern if you want to replace / extend an objects behaviour but you want to do it w/o the need to completely rewrite an objects functionality in whole. But others can describe that better than I.

like image 82
hakre Avatar answered Sep 29 '22 18:09

hakre