A primeira coisa diferente do comum em Orientação a Objetos, que aprendi foi o Polimorfismo, antes até de saber o que era, Singleton, Factory e etc… Eu estava trabalhando com PHP e precisava fazer umas classes de abstração que tinha que permitir usar Bancos de Dados, MySQL e Oracle. Ou seja, o desenvolvedor, poderia implementar usando MySQL ou Oracle, usando o mesmo pacote de abstração.
E então eu fui buscar uma forma de fazer, sem ter que gerar muita manutenção para o desenvolvedor e que se possível não tivesse que fazer IFs dentro do código.
E então, através de um amigo, ouvi falar do Polimorfismo na programação e fui pesquisar.
Bom, para os que não sabem o que é o Polimorfismo, o termo vem do grego e significa “Muitas formas” (Poli = Muitas , Morphos = Formas).
O Polimorfismo te da a condição de usar referências de tipos de classes mais abstratas para representar o comportamento de classes concretas.
Assim através de uma interface do tipo abstrato é possível tratar vários tipos diferentes de fazer uma mesma operação.
Atentando para o final da frase anterior, que mesmo possibilitando fazer várias coisas, o polimorfismo tem que representar muitas formas de fazer uma mesma coisa.
É como fazer NESTON, tem muitas formas. Mas nenhuma delas, faz o NESTON virar um NESCAL. hehe
Existem algumas formas de se implementar o Polimorfismo, se a maneira que você implementa faz uma representação de Polimorfismo, provavelmente estará certo.
Tipos de Polimorfismo
Existem três tipos de Polimorfismo ( Só lembrando que nem todas as linguagens de programação, suportam implementar todos esses tipos de Polimorfismo. )
- Universal
- Inclusão – um ponteiro para classe mãe pode apontar para uma instância de uma classe filha (exemplo em Usuarios autenticado = new UsuarioLogado(); (tipo de polimorfismo mais básico que existe)
- Paramétrico – se restringe ao uso de templates (C++, por exemplo) e generics (Java)
- Ad-Hoc
- Sobrecarga de métodos – (Dois métodos com mesmo nome, mas com assinaturas diferentes)
Vou demonstrar uma forma bem símples de entender e aplicar o Polimorfismo.
Primeiramente temos uma Interface que representará a base da polimorfia.
IOperacaoMatematica.cfc
<cfinterface> <cffunction name="calcular" access="public" returntype="Numeric"> <cfargument name="valX" type="numeric" required="true" /> <cfargument name="valY" type="numeric" required="true" /> </cffunction> </cfinterface>
Após a Interface criada, faremos as classes que implementarão essa Interface e serão passadas como referenência para implementar uma operação matemática.
OperacaoSoma.cfc
<cfcomponent implements="IOperacaoMatematica" output="false"> <cffunction name="calcular" access="public" returntype="Numeric"> <cfargument name="valX" type="numeric" required="true" /> <cfargument name="valY" type="numeric" required="true" /> <cfreturn arguments.valX + arguments.valY /> </cffunction> </cfcomponent>
OperacaoSubtracao.cfc
<cfcomponent implements="IOperacaoMatematica" output="false"> <cffunction name="calcular" access="public" returntype="Numeric"> <cfargument name="valX" type="numeric" required="true" /> <cfargument name="valY" type="numeric" required="true" /> <cfreturn arguments.valX - arguments.valY /> </cffunction> </cfcomponent>
A classe abaixo, fará a implementação das operações matemáticas utilizando o Polimorfismo.
Main.cfc
<cfcomponent output="false"> <cfscript> public Void function fazerCalculo( operacao , Numeric valX, Numeric valY ) { var instance = arguments.operacao; if( IsInstanceOf( instance , "OperacaoSoma" ) || IsInstanceOf( instance , "OperacaoSubtracao" ) ) { WriteOutput("Resultado: " &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; instance.calcular( arguments.valX , arguments.valY ) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; "<br />" ); } else { throw("Object","O argumento operação deve ter um objeto do Tipo <b>OperacaoSoma</b> ou <b>OperacaoSubtracao</b>"); } } public Void function executar() { var soma = CreateObject("component","OperacaoSoma"); var subtracao = CreateObject("component","OperacaoSubtracao"); this.fazerCalculo( soma , 10 , 2 ); this.fazerCalculo( subtracao , 10 , 2 ); } </cfscript> </cfcomponent>
Feito isso, só nos resta saber como executar:
<cfscript> variables.calculos = CreateObject("component","Main"); variables.calculos.executar(); </cfscript>
Como resultado teriamos algo como:
Resultado: 12
Resultado: 8
Bom, notaram como é simples?
Não há mistério, o conceito é esse, agora é pensar onde utilizar.
Veja mais detalhes de Arquitetura de Softwares nos links abaixo:
- Entendendo o padrão Composite
- Divisão da Responsabilidade
- Implementando a camada de Modelo
- Implementando a camada DAO
- Implementando uma arquitetura em camadas
- Uma visão sobre arquitetura de softwares
- Como começar um projeto de software
- Composição ou Herança
Abraços
Paulo Teixeira
Post original