13

Sempre quis saber exatamente, se é uma boa prática, fazer um sistema sempre fazendo uso de Interfaces, ou isso não é necessário?

Interface People {
  public function getName();
  public function setName($string);
  public function getAge();
  public function setAge($string);
}

class User implements People {

  private $name;
  private $age;

  public function __construct()
  {
   return $this; 
  }

  public function setName($string)
  {
     $this->name = $string;
     return $this;
  }

  public function getName()
  {
    return $this->name;
  }

  public function setAge($number)
  {
    $this->age = $number;
    return $this;
  }

  public function getAge()
  {
    return $this->age;
  }

}
2
  • Ivan, a vantagem principal que vejo é o cara não ter que ficar olhando o código da classe que faz algo, mas simplesmente saber a interface que a classe implementa +1 Commented 26/11/2015 às 11:48
  • Então, você vê isso como uma vantagem, um colega meu do trampo disse que eu deveria usar sempre nos meus sistemas, mas daí fico numa dúvida gritante, se a gente começa a criar um código mais burocrático, não fica uma coisa muito engessada? Commented 26/11/2015 às 11:51

2 Respostas 2

14

Necessário não é, mas é bom por vários motivos, documentar realmente é um deles, dar mais robustez no código é outro.

Só não entendo bem como linguagens de tipagem dinâmica investem tanto nisso, parece ir contra sua própria filosofia de deixar os testes ou intuição do programador detectar erros. Pior ainda quando a linguagem é de tipagem fraca.

A interface é um contrato que deve ser seguido quando fizer uma implementação. A tipagem de dados também é um contrato. Não sei porque ignoram uma forma e seguem outra. Talvez as próprias linguagens estejam admitindo aos poucos que elas usavam uma filosofia de tipagem errada, pelo menos para os objetivos mais importantes.

Existem linguagens de script e linguagens enterprise, entre outras, PHP era uma linguagem de script que agora quer ser uma linguagem enterprise, porém o legado não deixa fazer essa transição.

Então em um nível mais acima deve-se perguntar: por que vai usar uma medida protetora em uma linguagem que deixa de lado outras medidas protetoras mais importantes? Poucos se fazem esta pergunta, e muitos que a fizerem seriamente e conseguirem responder, vão decidir trocar de linguagem.

Claro que alguma medida protetora é melhor que nada, ela é vantajosa por si só, não só por isto.

Ela também generaliza (abstrai) o que está pretendendo fazer, e isso é bom. Este é um motivo até melhor para usar interface. Não vou explicar em detalhes aqui porque já há uma resposta sobre isso.

Em resumo, quando temos a interface implementada podemos usá-la para indicar que apenas aquilo que está presente nela é o que precisamos. E que qualquer classe que a implemente pode ser usada de forma concreta para satisfazer um algoritmo específico. Isto facilita a manutenção e a configuração da aplicação. Você não se prende à implementação concreta. As vantagens estão descritas na pergunta linkada acima.

Outras linguagens de script mais coerentes preferem o duck typing.

Ver mais em O que é estilo de tipagem?.

Coloquei no GitHub para referência futura.

13
  • 1
    Está caminhando para ter. As linguagens dinâmicas estão fazendo esta transição aos poucos. Umas mais rápidas que outras. Mas perceberam que elas estavam em um nicho que cada vez tem menos importância. Linguagens dinâmicas são de scripts. O problema é que elas começaram ser usadas para fazer aplicações. Agora perceberam que precisam de recursos de linguagem enterprise. Não podem mais se valer das mesmas facilidades que era ótimas para scripts.
    – Maniero
    Commented 26/11/2015 às 12:26
  • 3
    @KaduAmaral o problema é que quem quer uma linguagem robusta de verdade já não vai querer o PHP. Como ganhou bastante público, o PHP atraiu mais gente, e a linguagem começou a ganhar uma série de coisas "emprestada" das outras. E está ganhando os complicadores de uso também. Hoje tem quem faça uma classe imensa ou todo um projeto MVC pra fazer o que você precisaria em 2 ou 3 linhas usando as funções nativas proceduralmente. Perde performance e legibilidade, pra fazer o que aprendeu com as "boas práticas" (o tal ideal acadêmico), Mas se esquece que está usando PHP.
    – Largato
    Commented 26/11/2015 às 12:33
  • 3
    Ou seja, PHP é ótimo para fazer o que ele pretendia originalmente. Aí virou uma questão de marketing ter outras coisas pra "não ficar pra trás", o que descaracterizou a linguagem. Não tem problema em usar interfaces, OOP, design pattern complexo, o problema é querer fazer isto em PHP. Joga-se fora o que a linguagem oferece de melhor.
    – Maniero
    Commented 26/11/2015 às 12:37
  • 4
    @bigown aliás, acho que se PHP fosse burocrático, nunca teria "colado". A facilidade de uso e a velocidade com que você faz certas coisas em PHP foi o que ganhou o mercado. Agora, tem gente que fica se matando para "estruturar a aplicação", enquanto isso tem gente simplesmente sentando e escrevendo código para resolver o problema real, e a coisa sai funcionando bem. Não que eu ache isso ruim por si só, se você vai fazer um mega-framework pra distribuir pelo mundo. O duro é o cara fazer meia dúzia de aplicações diferentes e se preocupar com coisa que só vai penalizar o resultado final.
    – Largato
    Commented 26/11/2015 às 12:41
  • 2
    @WallaceMaxters se você vai usar um framework, é importante que ele esteja em ordem (seja OOP ou não, seja MVC ou não, isso é irrelevante), pois é uma aplicação que conceitualmente precisa estar consistente. Vai ser a base de muitas outras coisas. Diferente de uma aplicação ou site para uso específico, ou mesmo de algo que vai ficar naturalmente obsoleto, onde compensa ir direto ao ponto. Mais rápido, mais eficiente e fica mais fácil arrumar quando você descobre no meio do projeto aquelas coisas que não tinha como prever. Mas se vai usar framework, trabalhe da forma que ele diz pra trabalhar.
    – Largato
    Commented 26/11/2015 às 12:55
7

A principal vantagem que vejo disso no PHP é a questão de oferecer flexibilidade ao programador no caso de usar uma biblioteca onde ele implemente seu próprio recurso.

Nesse caso, o programador poderia simplesmente usar sua própria classe, desde que ele implemente a interface requerida para efetuar tal operação.

Um exemplo: Esses dias, estava tendo problema com a biblioteca do Facebook, pois eu uso o Laravel, e o Laravel não usa a sessão nativa do PHP. O Facebook usa a sessão nativa do PHP. O resultado é que estava tendo problema.

A classe do Facebook implementa uma interface chamada PersistentDataInterface. Essa interface possuía os métodos set e get, necessários para determinar a forma com que os dados seriam salvos na sessão.

Como a tipagem dos dados é feito através da PersistentDataInterface, eu a implementei, fazendo com que os métodos salvasse e obtivesse os dados direto da sessão do Laravel.

Assim, tudo funcionou corretamente.

Então veja um exemplo:

interface PersistentData {
    public function set($key, $value);
    public function get($key);
}

class Library{
      public function __construct(PersistentData $persist)
      {
            $this->persist = $persist;
      } 
}

class ClasseQueNaoAtendeMeuSistema implements PersistentData
{
     public function set($key, $value) { ... }
     public function get($key);
}

Veja nesse caso que, o construtor da classe Library exige que a tipagem seja a implementação da interface, e não da classe em si. Sendo assim, isso dá maior flexibilidade para que eu crie outra classe com os métodos da interface, porém que fazem a persistência dos dados de maneira diferente!

Creio que o uso da interface é uma boa prática quando você quer oferecer mais formas de sua biblioteca poder interagir com outras classe. Como você "obriga" a classe terceira a usar os métodos através da interface, pode chamar um método do objeto passado por parâmetro sem "ter medo" de que o método não exista e ter que ficar fazendo milhares de ifs com method_exists.

O FUTURO

No PHP7 será maravilhoso juntar o recurso das interfaces com as classes anônimas, pois isso dá mais flexibilidade ainda. Veja por exemplo, no caso acima, o que poderia ser feito.

$tempPersist = new class(Database::connection()) implements PersistentData
{
    public function __construct(Database $database)
    {
         $this->database = $database;
    }
    public function set($key, $value)
    {
       $this->database->table('session')->save([$key=>$value]);
    }  

    public function get($key)
    {
         return $this->database->table('session')->get($key);
    }
   
}


 $lib = new Library($tempPersist);
10
  • 3
    Mais flexibilidade do que já existe? O.o
    – rray
    Commented 26/11/2015 às 12:25
  • 3
    Está mais para "mais burocratização ainda"! Commented 26/11/2015 às 12:27
  • @IvanFerrer, seria mais burocrático se a biblioteca do facebook, no meu caso, só usasse a sessão do PHP. daí eu teria que cagar no meu código para o que eu precisava funcionasse de maneira correta. Programar também tem as suas partes burocráticas. Orientação a objetos é assim: pague agora e beneficie-se depois. Já as gambiarras estruturadas é : beneficie-se agora (da velocidade) e pague depois (com dores de cabeça nas alterações) Commented 26/11/2015 às 12:29
  • 2
    @IvanFerrer não são as empresas que estão atrasadas mas os programadores, veja a quantia de perguntas no sopt sobre o uso de funções obsoletas(mysql_*, ereg etc).
    – rray
    Commented 26/11/2015 às 12:39
  • 2
    @IvanFerrer, não vamos chamar de "pragas". Todo mundo já fez gambiarra um dia, inclusive eu. O problema de não saber e fazer um programa, é reconhecer que estava ruim e não consertar. Isso é que quebra a bicicleta. Já vi gente aqui no SOPT usando conexão com banco de dados feita na mão, sendo que estava usando o Laravel, que tem um modelo de abstração ótimo. O problema de errar é não corrigir Commented 26/11/2015 às 12:48

Você deve fazer log-in para responder a esta pergunta.

Esta não é a resposta que você está procurando? Pesquise outras perguntas com a tag .