Por que o PHP tem interfaces?


35

Notei que a partir do PHP5, as interfaces foram adicionadas à linguagem. No entanto, como o PHP é tão pouco digitado, parece que a maioria dos benefícios do uso de interfaces está perdida. Por que isso está incluído no idioma?


5
Eu acho que a pergunta correta é: por que não?
Alberto Fernández

5
porque eles não parecem oferecer nenhum benefício, então por que incluí-los?
precisa saber é o seguinte

4
O @HorusKol e antes de serem implementados, eles não eram usados, para que você possa ver como eles não eram usados ​​e inúteis apenas uma versão anterior. Você também deve fazer e apoiar a alegação de que seu uso é de alguma forma uma melhoria para dizer que eles são úteis.
91111 Rein Henrichs

6
@HorusKol Não é ilusório. É fácil demonstrar a proposta de valor do martelo. Esta pergunta está pedindo para alguém demonstrar a proposição de valor das interfaces PHP, não apenas para declarar que elas são valiosas de maneira argumentativa.
Rein Henrichs

3
E lembre-se de que as interfaces não são apenas sobre digitação. Uma interface é um contrato declarando que uma classe de implementação deve incluir os métodos estabelecidos. Útil para coisas como mecanismos de plugins.
Michael

Respostas:


30

A principal vantagem das interfaces no PHP é que as classes podem implementar várias interfaces. Isso permite agrupar classes que compartilham alguma funcionalidade, mas não necessariamente compartilham uma classe pai. Alguns exemplos podem incluir armazenamento em cache, saída ou acesso a propriedades da classe de uma certa maneira.

No seu código, você pode verificar se uma classe implementa uma determinada interface em vez de verificar o nome da classe. Em seguida, seu código ainda funcionará quando novas classes forem adicionadas.

O PHP fornece algumas interfaces predefinidas que podem ser úteis em várias situações: http://php.net/manual/en/reserved.interfaces.php .

EDIT - Adicionando um exemplo

Se você possui uma interface chamada MyInterface e está trabalhando com vários objetos de classes diferentes que podem ou não compartilhar alguma funcionalidade, as interfaces permitem que você faça algo assim:

// Assume $objects is an array of instances of various classes
foreach($objects as $obj) {
 if($obj instanceof MyInterface) {
     $obj->a();
     $obj->b();
     $obj->c();
   }
}

23
Em outras palavras: "você pode ignorar completamente todos os benefícios das linguagens de tipo dinâmico"
Kamil Tomšík

11
@ Kamil, penso nisso mais como poder tirar proveito dos benefícios da digitação estática sem sofrer os inconvenientes quando você não os deseja.
Karl Bielefeldt

9
você está falando sério? instancia de? se-então-se-então-se-então-sempre-não-parece familiar? ah, sim, programação procedural.
Kamil Tomšík

23
@Kamil Tomšík Mais um insulto à linguagem do PHP, e não às pessoas que o usam de maneira incompetente. O PHP possui todas as ferramentas para programação completa orientada a objetos. A utilização ou não dessas informações depende do programador. Além disso, não há nada errado com a programação procedural por si só.
Lotus Notes

18
@ Kamil - que estranho, lendo seu comentário, pode-se concluir que não existem if-s no OOP e que, de alguma forma, magicamente - as coisas começam a funcionar. Uau.
Michael JV

23

O PHP é pouco digitado, mas pode ser fortemente digitado sobre coisas como parâmetros de método.

Considere o seguinte exemplo:

interface Car { function go(); }

class Porsche { function go() {} }

function drive(Car $car) {}

$porsche = new Porsche();

drive($porsche);

O código acima produziria:

O argumento 1 passado para drive () deve implementar a interface Car, instância da Porsche dada


11
Claro, é muito ruim. Você pode ter um nullvalor padrão para o parâmetro.
Emanuil Rusev

5
mas se driverequer um Car, em seguida, passando nullnão seria de qualquer maneira muito útil ...
HorusKol

7
Nunca passe nulo. Use um objeto "Caso especial" (explicação do Google para Martin Fowler).
Martin Blore

2
@ Renesis Se você definir o valor padrão como nulo, poderá passar nulo para métodos com dicas de tipo. (CAR $ car = null) permitiria que você chamasse esse método com null como argumento. Essa seria uma prática bem boba, no entanto. Por que diabos você gostaria de fazer isso?
Dqhendricks

2
Exemplo concreto: function addView($name, Template $template, SecurityMode $securityMode = null, $methodName = null);você pode ter um $methodNamemas não $securityMode.
22611 Nicole

7

As interfaces permitem implementar o princípio de aberto-fechado, manter uma base de código fracamente acoplada e implementar muitos dos melhores padrões de design de OOP.

Por exemplo, se uma classe aceita outra classe como argumento:

class A {

    public function __construct(B $class_b) {
        // use class b
        $class_b->run();
    }
}

Sua classe A e classe B agora têm um acoplamento rígido, e a classe A não pode usar nenhuma outra classe, exceto B. A dica de tipo garante que você tenha o tipo correto de argumento, mas agora cimentou o relacionamento entre A e B.

Digamos que você deseja que a classe A possa usar todos os tipos de classes que possuem um método run () no entanto. Esse é basicamente (mas não exatamente) o padrão de design do COMMAND. Para resolver, digite a dica usando uma interface em vez de uma classe concreta. B implementariam essa interface e serão aceitos como argumento para a classe A. Dessa forma, a classe A pode aceitar qualquer classe que use essa interface como argumento para seu construtor.

Esse tipo de codificação é usado na maioria dos padrões de design de OOP e permite alterações de código MUITO mais fáceis posteriormente. Isso faz parte dos fundamentos da programação AGILE.


11
Ou qualquer subclasse de B
Mez

7

@pjskeptic tem uma boa resposta e @Kamil Tomšík tem um bom comentário sobre essa resposta.

A grande coisa sobre linguagens dinamicamente tipadas como PHP é que você pode tentar usar métodos em objetos e ele não gritará com você, a menos que o método não esteja lá.

O problema com linguagens dinamicamente tipadas como PHP é que você pode tentar usar métodos em objetos e isso gritará com você quando o método não estiver lá.

As interfaces adicionam uma maneira conveniente de chamar métodos em um objeto desconhecido e ter certeza de que os métodos estão lá (não que estejam necessariamente corretos ou que funcionem). Não é uma parte necessária de um idioma, mas torna a codificação mais conveniente. Ele permite que os desenvolvedores OOP fortemente tipificados escrevam código PHP fortemente tipado, que pode trabalhar junto com o código PHP vagamente digitado, escrito por um desenvolvedor PHP diferente.

uma função como:

foo( IBar $bar )
{
  $baz = $bar->baz();
  ...
}

é mais conveniente do que:

foo( $bar )
{
  if ( method_exists( $bar, 'baz' ) )
  {
    $baz = $bar->baz();
  }
  else
  {
    throw new Exception('OMGWTF NO BAZ IN BAR!');
  }
  ...
}

e IMHO código simples e legível é melhor código.


11
o que você faz não é apenas verificar o método, travar e gravar quando alguém chama sua função com os dados errados. Não é problema seu se alguém usar sua função incorretamente.
Raynos 15/05

não exatamente - seu exemplo é pesadelo para qualquer um que quer passar qualquer "pato" dinâmico, como proxy, adaptador, decorador etc.
Kamil Tomšík

11
@Kamil? Como assim. Um proxy seria uma classe de invólucro para algo que não implementa a interface para permitir que ela seja usada com esta função.
tylermac

@tylermac proxy dinâmico usando __call () - e se __call é o único método lá, ele simplesmente não pode implementar IBar, o que significa que você não pode passá-lo para foo (IBar $ bar)
Kamil Tomšík

5

Eles são completamente inúteis se você é pato-typer; na verdade, quando você faz pato-digitação, é muito chato trabalhar com bibliotecas / framework que usam qualquer dica de tipo.

Isso se aplica também a todos os tipos de metaprogramação dinâmica (métodos mágicos).


3

PHP não é vagamente ou fortemente, mas digitado dinamicamente .

Sobre interfaces, a primeira coisa que você deve se perguntar é: quais são os principais benefícios das interfaces?

No OOP, as interfaces não são apenas sobre tipos, mas também sobre comportamento.

Como o PHP também possui um recurso de dica de tipo , você pode usar interfaces como faria em uma linguagem oo pura, como Java.

interface File
{
    public function getLines();
}

CSVFile implements File
{
    public function getLines()
    {}
}

XMLFile implements File 
{
    public function getLines()
    {}
}

JSONFile implements File 
{
    public function getLines()
    {}
}

class FileReader
{
    public function read(File $file)
    {
        foreach($file->getLines() as $line)
        {
            // do something
        }
    }
}

Com a implementação da interface PHP, você também pode criar simulações para classes abstratas usando o PHPUnit - e esse é um recurso incrível:

public function testSomething()
{
    $mock = $this->getMockForAbstractClass('File');

    $mock->expects($this->once())
         ->method('getLines')
         ->will($this->returnValue(array()));

    // do your assertions
}

Portanto, basicamente, você pode ter um aplicativo compatível com SOLID em PHP usando os recursos de linguagem, sendo um deles interfaces.


0

As interfaces são úteis para injeção de dependência muito mais do que concreto. Como exemplo de barebones:

interface Istore { 
  public function save(); 
}

class Article_DB implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}

class Article
{
   private $content;

   public function content($content)
   {
     $this->content = $content;
   }

   public function save(Istore $store)
   {
     $store->save($this->content);
   }
}

$article = new Article();
$article->content('Some content');

$store = new Article_DB();
$article->save($store);

Agora diga se suas necessidades mudam e você deseja salvar em um pdf. Você pode criar uma nova classe para esse fim, em vez de poluir a classe Article.

class Article_PDF implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}


$article = new Article();
$article->content('Some content');

$store = new Article_PDF();
$article->save($store);

A classe Article agora tem um contrato que as classes usadas para salvar devem implementar a interface do Istore. Ele não se importa onde ele salva ou como ele salva.


-1

Você pode fornecer objetos reais "Falsos" que implementam a interface. Em seguida, você poderia testar uma unidade do seu código sem exigir servidores, sistemas de arquivos, soquetes, bancos de dados reais etc.


-3

Muitas pessoas provavelmente me odeiam por responder dessa maneira, mas a solução para seus problemas de digitação pode ser facilmente corrigida com o PHP. Sim, o PHP é pouco digitado, de modo que os tipos são assumidos por padrão, o que pode causar alguns problemas, especialmente em operações de comparação, que é o problema da maioria das pessoas. Dito isto, o PHP pode ser tão rigoroso quanto qualquer linguagem fortemente tipada se você converter o que está usando no tipo que precisa e, em seguida, usar operadores de comparação bit a bit. Aqui está o exemplo mais fácil que consigo pensar no que estou dizendo:

$ myVar = (int) 0; $ myOtherVar = '0';

comparar ($ myVar == $ myVar) seria igual a (bool) true

mas comparar ($ myVar === $ myVar) seria igual (bool) false como qualquer comparação "digitada"

Eu realmente gostaria que os desenvolvedores parassem de discutir sobre essas coisas, se você tiver um problema com a maneira como o PHP funciona, vá para o programa em java e viva e deixe viver, ou use-o da maneira que ele fará o que você deseja. De qualquer forma, de que reclamar é bom para você? Dá uma desculpa para se meter o dia todo? Faz você parecer melhor que outra pessoa? Bem, é ótimo você se sentir tão bem consigo mesmo que está disposto a fazer com que outra pessoa pareça ruim, mas, na realidade, é sua preferência e forçar suas crenças a alguém realmente faz com que ela codifique de uma maneira que não se sinta confortável em causar três coisas:

1) Eles irão codificar seu caminho, mas "bagunçados" para seus padrões (pense, você já viu um programador java criar seu primeiro programa PHP ou vice-versa? Será da mesma maneira que mudar sua metodologia ou talvez ainda pior.)

2) Você encontrará outra coisa para reclamar

3) Provavelmente levará mais tempo para eles produzirem. E talvez isso faça você parecer melhor a curto prazo, mas a equipe como um todo parecerá pior (lembre-se de que você pode codificar mais devagar que qualquer outra pessoa e isso não é necessariamente ruim, desde que a equipe atenda às entregas em um prazo razoável, mas forçar seus hábitos a alguém que normalmente se saiu um pouco mais rápido pode acabar diminuindo a velocidade de toda a sua equipe, ficando pior em um fluxo de trabalho muito exigente)

Pessoalmente, prefiro escrever código PHP processual, embora eu possa e tenha escrito programas completos usando OOP em algumas linguagens diferentes. Dito isto, eu vi um bom código OOP e um código ruim OOP, e um bom código processual e um código processual ruim para esse assunto ... Realmente não tem nada a ver com a prática, mas com os hábitos que você usa e mesmo assim, muitas coisas são meus sentimentos interpretados ... isso não significa que vou falar mal desses desenvolvedores ou dizer que me gabo com "meu jeito é o melhor" BS, é o ideal para mim, e a empresa em que trabalho é bonita feliz com o meu trabalho e tenho orgulho disso. Existem razões pelas quais um padrão deve ser estabelecido, mas o que você inclui no padrão escolhido é MUITO importante ... Obrigado por me deixar tirar isso do peito. Tenha um ótimo dia.


-4
  1. Interfaces faz parte do paradigma OOP. Portanto, é muito útil em muitos casos, quando você tenta criar peças orientadas a objetos ou seu sistema.
  2. Tão. Por que não? ;-)

Exemplos: você precisa armazenar em cache seus dados. Quão? Existem muitos mecanismos diferentes para armazenamento em cache, qual é o melhor? Quem se importa se você tem uma camada abstrata que possui alguma interface do ICacheDriver com um conjunto de métodos como chave, obtém, coloca, limpa, etc. Basta implementar o que você precisa no projeto atual e alterá-lo quando precisar de outro. Ou uso simples de toString. Você tem um conjunto de diferentes objetos mostráveis. Você acabou de implementar a interface Stringable (que descreve o método toString [realmente não há interfaces como essa no PHP, mas por exemplo]) e apenas interagindo sobre todo o seu objeto com (string) $ obj. Tudo o que você precisa fazer é alternar (true) {case $ obj isance of A1: "do 1"; quebrar; ...}

Simples. Portanto, não há pergunta "Por quê?". Existe "como usar isso melhor?". ;-) Boa sorte.


-5

Meu palpite.

O PHP é usado por muitos programadores iniciantes , os programadores iniciantes são ensinados java na faculdade.

Após o curso de Programação 101, eles começam a incomodar o Zend e querem os recursos java porque é assim que eles aprendem a pensar, é difícil pensar em seus próprios termos (ou entender a digitação de pato) quando você tem apenas 20 anos.

O Zend é pragmático, é mais fácil adicionar o recurso do que fingir que está certo o tempo todo.
Isso também compra mais usuários em vez de fazê-los sair, por isso deve ser bom.

Outra instância deste processo? As pessoas que acabaram de sair dos cursos .NET e Java também querem Frameworks of Foundation Classes , ficam preocupadas com isso até o Zend lançar o Zend Framework . Isso compra ainda mais usuários. E assim por diante...

(o único recurso de linguagem que a equipe do PHP sabe ter lutado ao longo dos anos goto)


Na minha visão, PHP12provavelmente terá todos os recursos de sintaxe do mundo (espero que ele não tenha um tempo de execução da camada de abstração, difícil, pois foi isso que matou o perl) com uma piscada para paradigmas funcionais e de tipo de dados, e ainda não goto.
ZJR

"é difícil quando você tem apenas 20 anos" Como a idade poderia ter alguma coisa a ver com a compreensão de algum desses conceitos?
Evicatos

Os alunos do @Evicatos são um tipo de programa, mas geralmente têm maus professores, más convenções de nomenclatura e produzem bolhas inatingíveis. Eles aprendem a programar corretamente quando começam a faculdade, leva alguns anos para começar. Então eles começam a divergir dos idiomas difíceis de digitar, abençoados pela indústria e aclamados pela academia, que foram ensinados nos primeiros anos, e se voltam para os mais pragmáticos e tipográficos. Eu acredito que este é um bushido que muitos programadores compartilham. Então, novamente, isso pode não refletir sua experiência, você pode ser um sábio autodidata. Se sim, mostre-nos o caminho.
ZJR
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.