Consider the following three scenarios:
class Dog {
...
public function Bark($str) {
echo $str;
}
...
}
class AnimalCommunication {
...
public function DogBark(Dog $dog, $str) {
$dog->Bark($str);
}
...
}
class Dog {
...
public function Bark($str) {
echo $str;
}
...
}
class AnimalCommunication {
...
public function AnimalCommunicate($str) {
echo $str;
}
...
}
Interface IAnimal {
public function Speak($str);
}
Class Dog implements IAnimal {
...
public function Speak($str) {
$this->Bark($str);
}
....
}
class AnimalCommunication {
...
public function AnimalCommunicate(IAnimal $animal, $str) {
$animal->speak($str);
}
...
}
Note the following about these examples:
- The first is tightly coupled to the dog class, and hence is not very extensible.
- The second is coupled to echo. It does not allow different “animals” to output their text differently. What if we later added a
TelepathicGecko
class, which didn’t echo out to speak, but rather published to some ESP API somewhere? Clearly the coupling here is not ideal either. - The third is best. By programming to an interface, we reduce coupling to the minimum necessary amount.