I wonder if it would be practical to add an implementedBy keyword to PHP or other OO programming languages. I imagine it could help a lot with keeping application code decoupled from third party library code, and following the interface segregation principle.
For instance if I work at Acme and I want to use the Money PHP library, but not couple my code to it directly, I could write an interface with just the methods I need:
<?php
namespace Acme;
interface Money implementedBy \Money\Money
{
public function greaterThan(Money $other);
public function getAmount();
public function multiply($multiplier, $roundingMode = self::ROUND_HALF_UP);
}Then I'd write business logic code with type hints for Acme\Money instead of Money\Money:
<?php
namespace Acme
class RegularPayment
{
/** @var Money */
private $sum;
/** @var \DateInterval */
private $period;
public function __construct(Money $sum, \DateInterval $period)
{
$this->sum = $sum;
$this->period = $period;
}
public function getAnnualTotal() : Money
{
return $this->sum->multiply(365/$period->d);
}
}If I wanted to switch to a different implementation later I'd just have either arrange for it to explicitly implement Acme\Money, or add its name to the implementedBy statement.
Markku Sakkinen, Philippe Lahire and Ciprian-Bogdan Chirila proposed a similar idea for the Eiffel language, but I don't know if anything like it has been implemented in any language. Towards Fully-fledged Reverse Inheritance in Eiffel. 11th Symposium on Programming Languages and Software Tools (SPLST’09), Aug 2009, Tampère, Finland. pp.1-16, 2009.
Given that this keyword isn't currently available in PHP, the closest equivilent is probably:
<?php
namespace Acme
class Money extends \Money\Money implements Interfaces\Money
{
// block intentionally left empty
}<?php
namespace Acme\Interfaces;
interface Money
{
public function greaterThan(Money $other);
public function getAmount();
public function multiply($multiplier, $roundingMode = self::ROUND_HALF_UP);
}And then write the business logic code like RegularPayment to type hint against the \Acme\Interfaces\Money rather than either \Money\Money or \Acme\Money. This achieves almost the same ends of interface segregation and loose coupling as the hypothetical implementedBy keyword would, while probably being less confusing.