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.