O que é polimorfismo?
Polimorfismo é uma palavra muito tempo para um conceito muito simples.
Polimorfismo descreve um padrão de programação orientada a objeto em que as classes têm diferentes funcionalidades ao compartilhar de uma interface comum.
A beleza do polimorfismo é que o código de trabalho com as diferentes classes, não precisa saber qual a classe que está usando desde que todos eles são usados da mesma forma.
A analogia com o mundo real para o polimorfismo é um botão. Toda a gente sabe como usar um botão: você simplesmente pressionar a ele. O que um botão "não", entretanto, depende do que ele está conectado e do contexto em que ela é usada - mas o resultado não afeta a forma como é utilizado. Se o seu patrão lhe diz para pressionar um botão, você já tem todas as informações necessárias para executar a tarefa.
No mundo da programação, polimorfismo é usado para fazer aplicações mais modular e extensível. Em vez de declarações condicionais bagunçado descrevendo os diferentes cursos de ação, você cria objetos intercambiáveis que você selecionar com base em suas necessidades. Esse é o objetivo básico de polimorfismo.
Interfaces
Uma parte integrante do polimorfismo é a interface comum. Existem duas maneiras de definir um interface em PHP: interfaces e classes abstratas. Ambos têm seus usos, e você pode misturar e combinar-los como quiser em sua hierarquia de classe.
Usando uma interface
Uma interface é similar a uma classe, exceto que ele não pode conter código. Pode definir nomes de métodos e argumentos, mas não o conteúdo dos métodos. Todas as classes que implementam uma interface deve implementar todos os métodos definidos pela interface. Uma classe pode implementar várias interfaces.
Uma interface é declarado usando a ' interface
'palavra-chave:
(interface MyInterface
/ / Métodos
)
e está associado a uma classe usando o ' implements
'palavra-chave:
MyClass classe implementa (MyInterface
/ / Métodos
)
Métodos podem ser definidos na interface, tal como em uma classe, exceto sem o corpo (a parte entre as chaves):
(interface MyInterface
DoThis função pública ();
doThat função pública ();
setName função pública ($ name);
)
Todos os métodos definidos aqui terá de ser incluído em qualquer implementação de classes exatamente como descrito. (Nota: os comentários de código abaixo.)
/ / Válido
MyClass classe implementa (MyInterface
$ nome pública;
público DoThis function () (
/ / Código que faz isso
)
doThat função pública () (
/ / Código que faz isso
)
setName função pública ($ name) (
$ This-> nome = $ nome;
)
)
/ / Inválido
MyClass classe implementa (MyInterface
/ / DoThis falta ()!
doThat função pública () (
/ / Este deve ser público!
)
público setName function () (
/ / O argumento de falta nome!
)
)
Usando uma classe abstrata
Uma classe abstrata é uma mistura entre uma interface e uma classe. Pode definir a funcionalidade, bem como interface (na forma de métodos abstratos). Classes estender uma classe abstrata deve implementar todos os métodos abstratos definidos na classe abstrata.
Uma classe abstrata é declarada da mesma forma que as classes com a adição do " abstract
palavra-chave ":
MyAbstract classe abstrata (
/ / Métodos
)
e está associado a uma classe usando o ' extends
'palavra-chave:
Class MyClass (estende MyAbstract
/ / Métodos da classe
)
métodos regulares podem ser definidos em uma classe abstrata, tal como em uma classe regular, bem como de quaisquer métodos abstratos (usando o ' abstract
'palavra-chave). métodos abstratos se comportam exatamente como os métodos definidos em uma interface, e deve ser implementado exatamente como definido pela extensão classes.
MyAbstract classe abstrata (
protected $ nome;
público DoThis function () (
/ / Fazer isso
)
resumo doThat função privada ();
resumo setName função pública ($ name);
)
Passo 1: identificar o problema
Vamos imaginar que você tem um Article
classe que é responsável pela gestão de artigos em seu site. Ele contém informações sobre um artigo, incluindo o título, autor, data e categoria. Aqui está o que parece:
poly_base_Article classe (
$ titulo pública;
autor $ público;
$ date pública;
categoria $ público;
public function __construct ($ title, $ autor, data, $ categoria = 0) (
$ This-> title = $ title;
$ This-> author = $ autor;
$ This-> data = $ data;
$ This-> categoria = $ categoria;
)
)
Nota: As classes de exemplo neste tutorial usa a convenção de nomenclatura de "package_component_Class." Esta é uma maneira comum de classes separadas em namespaces virtuais para evitar colisões de nomes.
Agora você quer adicionar um método para a produção da informação em diferentes formatos, como XML e JSON. Você pode estar tentado a fazer algo como isto:
poly_base_Article classe (
//...
public function escreve ($ type) (
''Ret = $;
switch ($ tipo) (
caso 'XML':
$ ret = '<article>;
$ ret .= '<title>. título $ obj->. '</ Title> ";
$ ret .= '<author>. autor $ obj->. '</ Autor>';
$ ret .= '<data>. data $ obj->. '</ Data>';
$ ret .= '<category>. categoria $ obj->. "</> Categoria ';
$ ret .= '</ artigo>';
break;
case 'JSON':
array $ array = ('artigo' => $ obj);
$ Ret = json_encode ($ array);
break;
)
return $ ret;
)
)
Esta é uma espécie de solução feio, mas funciona - por agora. Pergunte a si mesmo o que acontece no futuro, no entanto, quando queremos adicionar mais formatos? Você pode continuar editando a classe, adicionando mais e mais casos, mas agora você só está diluindo sua classe.
Um princípio importante da OOP é que uma classe deve fazer uma coisa, e deve fazê-lo bem.
Com isto em mente, as declarações condicional deve ser uma bandeira vermelha, indicando que a classe está tentando fazer muitas coisas diferentes. Este é o lugar onde o polimorfismo vem dentro
No nosso exemplo, é claro que existem duas tarefas apresentadas: artigos de gestão e formatação de seus dados. Neste tutorial, vamos refazer a nossa vontade de formatação de código em um novo conjunto de classes e descubra como é fácil utilizar polimorfismo.
Passo 2: Defina sua interface
A primeira coisa que devemos fazer é definir a interface. É importante pensar muito sobre a sua interface, pois qualquer alteração pode exigir alterações para o código de chamada. Neste exemplo, vamos estar usando uma interface simples para definir o nosso método um:
poly_writer_Writer (interface
public function escreve (poly_base_Article $ obj),
)
É tão simples, temos um público definido write()
método que aceita um objeto como um argumento do artigo. Qualquer classe que implementa a interface do escritor ter a certeza de que este método.
Dica: Se você quiser restringir o tipo de argumentos que podem ser passados para as funções e métodos, você pode usar as dicas, tipo como fizemos no write()
método, que só aceita objetos do tipo poly_base_Article
. Infelizmente, o tipo de retorno insinuando não é suportado nas versões atuais do PHP, por isso é até você para tomar conta de valores de retorno.
Passo 3: Criar a sua implementação
Com sua interface definida, é hora de criar as classes que realmente fazem coisas. No nosso exemplo, temos dois formatos que queremos para a saída. Assim, temos duas classes Escritor: XMLWriter e JSONWriter. Cabe a estes para extrair os dados do objeto do artigo passou e formatar as informações.
Aqui está o que parece XMLWriter:
poly_writer_XMLWriter classe implementa (poly_writer_Writer
public function escreve (poly_base_Article $ obj) (
$ ret = '<article>;
$ ret .= '<title>. título $ obj->. '</ Title> ";
$ ret .= '<author>. autor $ obj->. '</ Autor>';
$ ret .= '<data>. data $ obj->. '</ Data>';
$ ret .= '<category>. categoria $ obj->. "</> Categoria ';
$ ret .= '</ artigo>';
return $ ret;
)
)
Como você pode ver a partir da declaração da classe, nós usamos a implements
-chave para implementar a nossa interface. O write()
método contém funcionalidades específicas para a formatação XML.
Agora aqui é a nossa classe JSONWriter:
poly_writer_JSONWriter classe implementa poly_writer_Writer (
public function escreve (poly_base_Article $ obj) (
array $ array = ('artigo' => $ obj);
json_encode retorno ($ array);
)
)
Todos os nossos código específico para cada formato agora está contida dentro de classes individuais. Essas classes têm cada um a responsabilidade de lidar com um formato específico, e nada mais. Nenhuma outra parte do seu aplicativo precisa se preocupar com a forma como estes trabalhos, a fim de usá-lo, graças à nossa interface.
Etapa 4: Use a sua implementação
Com a nossa nova classe definida, é hora de rever a nossa classe artigo. Todo o código que viveu no original write()
método tem sido fatorado em nosso novo conjunto de classes. Todos os nosso método tem a fazer agora é usar as novas classes, como este:
poly_base_Article classe (
//...
public function escreve ($ poly_writer_Writer escritor) (
retorno escrever $ escritor-> ($ this);
)
)
Todos esse método não é agora aceitar um objeto da classe Writer (ou seja, qualquer classe que implementa a interface do Writer), o seu apelo write()
método, passando-se ( $this
) como argumento, em seguida, encaminhar o valor de retorno direto para o cliente código. Ele não precisa mais se preocupar com os detalhes da formatação de dados, e pode se concentrar em sua tarefa principal.
Obtenção de um escritor
Você pode estar se perguntando onde você obtém um objeto Writer, para começar, pois você precisa passar uma a este método. Isso é até você, e há muitas estratégias. Por exemplo, você pode usar uma classe de fábrica para pegar dados do pedido e criar um objeto:
poly_base_Factory classe (
getWriter função pública estático () (
/ / Pega variável pedido
formato formato = $ _REQUEST ['];
/ / Construir o nosso nome da classe e verificar a sua existência
$ class = "poly_writer_. formato $. "Escritor";
if (class_exists ($ class)) (
/ / Retorna um objeto novo escritor
novo retorno $ (classe);
)
/ / Caso contrário, não
throw new Exception ("formato não suportado");
)
)
Como eu disse, existem muitas outras estratégias para usar dependendo de suas necessidades. Neste exemplo, uma variável de solicitação escolhe qual o formato a utilizar. Ele constrói um nome de classe da variável pedido, verifica se ela existe, em seguida, retorna um objeto novo escritor. Se não existe nenhum com esse nome, uma exceção é acionada para deixar o código do cliente descobrir o que fazer.
Passo 5: Put It All Together
Com tudo em seu lugar, aqui é como o nosso código do cliente que juntar tudo isso:
artigo = $ poly_base_Article novo ('polimorfismo "," Steve "tempo, (), 0);
try (
escritor $ = poly_base_Factory: getWriter ();
)
catch (Exception $ e) (
escritor poly_writer_XMLWriter $ = new ();
)
echo $ artigo-> write ($ escritor);
Primeiro criamos um artigo exemplo de objeto para trabalhar com ele. Então, tentamos obter um objeto Writer da fábrica, caindo de volta a um padrão (XMLWriter) se uma exceção é lançada. Finalmente, passar o objeto de nosso artigo do escritor de write()
método, a impressão do resultado.
Conclusão
Neste tutorial, eu tenho desde que com uma introdução ao polimorfismo e uma explicação de interfaces em PHP. Eu espero que você perceber que eu só mostrei um caso de uso potencial para o polimorfismo. Há muitas, muitas outras aplicações. O polimorfismo é uma maneira elegante de escapar feio declarações condicionais no código POO. Ele segue o princípio da conservação dos seus componentes em separado, e é parte integrante dos padrões de design. Se você tiver alguma dúvida, não hesite em perguntar nos comentários!
Nenhum comentário:
Postar um comentário