dog = new Dog()
// ...
// Não importa se é um Cão, Lobo ou Gato, apenas quero saber se vai latir.
// A medida que os requisitos mudarem, pode haver outras
// formas de latir, porém, esse trecho de código continuará operando
//
// O que se deve levar em consideração é o que o método .bark() retorna,
// uma string ou um objeto/function? deve se pensar na abstração,
// pois não importa o paradigma, se variar o retorno, terá que dar manutenção
// igual no trecho seguinte..
// Sem uma abstração, quem garantirá que existirá o método .bark()?
function (Barkinterface bark) {
// ...
}
Exemplo com PHP:
// Vamos imaginar que o array abaixo tem varios objetos, dentro dele: cães, gatos, cavalos,
// lobos e até pessoas, e gostaria de pegar apenas os que latem
$animals = [/*...*/];
$barkAnimals = array_filter($animals, function ($animal) {
return $animal instanceof BarkableInterface;
});
// Neste ponto, eu tenho apenas animais que latem, além de `$animals`, não mutando os dados..
// Objetos são passados por referência, uma forma ainda melhor seria colocar:
// return clone $animal para evita que alguma modifição em objetos pertencente a $barkAnimals
// reflita em $animals