Simple Wrapper
We write conditionals all the time. Often, we check for very simple things, not worth any extra effort of encapsulation. But in many cases, this makes perfect sense even for very basic things. Let me give you an example:
$date = new \DateTime('2016-05-15');
if ($date->format('N') == 6 || $date->format('N') == 7) {
// do something
}
If you are like me, you always have to look up, that N
is the character you need when you want to check for a specific day of the week. Or was it w
? Well, yes, but then the Sunday is represented as 0
instead of 7
. Whoo, lots of boring stuff to remember.
Now even if this is the only place in your entire code base that needs this check, this will always be a place where a fellow developer or your future self will stop and needs to think for some seconds what this means.
Now consider this:
$date = new DateTime('2016-05-15');
if ($date->isWeekend()) {
// do something
}
Inheritance
This is way better to read, no need to think about that at all. If you own that class by yourself you can of course simply add that functionality. But in case you do not, all you need to do is to extend the class you want to do the check on.
namespace MyApp;
class DateTime extends \DateTime
{
public function isWeekend()
{
return $this->format('N') == 6 || $this->format('N') == 7;
}
}
Now you never have to worry about the characters to use in the format
-method or what numbers to use.
Delegation
While inheritance seems the easiest way to achieve this, it comes with a drawback. Your class now completely depends on changes of the original underlying class. If for some reason the public API of it changes, your public API changes as well.
So instead you could use delegation:
namespace MyApp;
class DateTime
{
private $dateTime;
public function __construct(\DateTime $dateTime)
{
$this->dateTime = $dateTime;
}
public function isWeekend()
{
return $this->format('N') == 6 || $this->format('N') == 7;
}
public function format($format)
{
return $this->dateTime->format($format);
}
}
Now you when the public API of the underlying class changes, only your wrapper breaks - but not your whole application. The drawback here is that you have to delegate all the methods you want to use. This might seem stupid at first glance, but it gives you the complete control over what can be done with your class and what not.