Ao utilizar interfaces para certas classes eu tenho um ganho enorme na aplicação para a criação de novas classes. Os méritos da interface são muitos, mas vou me focar em um problema que eu não consigo resolver:
Caso eu tenha uma interface Peça e classes implementando ela, no caso, por exemplo, peão, torre… A interface é declarada com um método apenas: movimentaPeça();
Todas as classes filhas implementam o método movimentaPeça.
Daqui a dois anos, por exemplo, um usuário me pede que as peças façam algo diferente: capturarPecaAdversaria(). Aqui vem o problema, imaginem que eu tenho umas 20 classes implementando Peça, agora eu terei que implementar em todas as peças…
Imaginem ainda, que eu não quero que todas as peças tenham esse movimento de captura, digamos, das 20 classes, apenas 5 precisariam implementar isso.
Qual seria a melhor maneira de contornar esse problema?
Se eu entendi direito… A classe helper não funcionaria. O problema maior é em ter que mudar a interface e ter que mudar todas as implementações.
Tive que criar um método novo na interface. PQP :oops: Aí terei que implementar em todas as suas Implementações. Tenho pesquisado, me falaram do padrão bridge, mas não entendi ainda como ele pode servir nesse caso
[quote=andersonlandim]Foi mal não ter respondido anteriormente… hehe
Se eu entendi direito… A classe helper não funcionaria. O problema maior é em ter que mudar a interface e ter que mudar todas as implementações.
Tive que criar um método novo na interface. PQP :oops: Aí terei que implementar em todas as suas Implementações. Tenho pesquisado, me falaram do padrão bridge, mas não entendi ainda como ele pode servir nesse caso
vlw![/quote]
Anderson,
Você pode resolver esse tipo de problema de várias formas.
Se você vai ter que aplicar o comportamento novo em uma ou duas classes porque não definir uma nova interface? (Decorator Pattern, Visitator Pattern).
Agora se você precisa realmente adptar o método da interface sugiro o padrão Adapter.
Por isso eu acho o duck typing fantástico. Em outra linguagens, como Python, Ruby e escala, vc simplesmente passa a chamar o método e implementa só para as classes que precisarem, podendo executar um método default para as classes que não implementem o método.
Mas como o Fórum é de Java…rs
[quote=renzonuccitelli]Por isso eu acho o duck typing fantástico. Em outra linguagens, como Python, Ruby e escala, vc simplesmente passa a chamar o método e implementa só para as classes que precisarem, podendo executar um método default para as classes que não implementem o método.
Mas como o Fórum é de Java…rs[/quote]
Isso se chama Herança e Polimorfismo no Java.
Edit: Apesar de não ter o caráter dinâmico dessas linguagens é possível fazer com uma boa modelagem orientada a objetos.
Eu acho o Duck Typing bem ágil, porem o uso excessivo dele pode denotar um modelo OO ruim!
[quote]Se você vai ter que aplicar o comportamento novo em uma ou duas classes porque não definir uma nova interface? (Decorator Pattern, Visitator Pattern).
Agora se você precisa realmente adptar o método da interface sugiro o padrão Adapter.[/quote]
Concordo, o decorator pattern parece realmente uma boa ideia nesse caso…
Acho que isso tem mais a ver com o gosto por linguagens dinâmicas.
Em linguagens estáticas há, como já dito acima, várias opções para resolver este tipo de coisa.
A sua solução (implementação padrão para quem não possui e específica para alguns) pode ser implementada sem duck typing.
Acho que isso tem mais a ver com o gosto por linguagens dinâmicas.
Em linguagens estáticas há, como já dito acima, várias opções para resolver este tipo de coisa.
A sua solução (implementação padrão para quem não possui e específica para alguns) pode ser implementada sem duck typing.
Até onde sei, não há duck typing em Scala. [/quote]
Duck Typing no Scala. Inclusive no Scala é type safety, muito bom pra quem gosta de ver os erros ainda em tempo de compilação.
[quote=renzonuccitelli] Duck Typing no Scala. Inclusive no Scala é type safety, muito bom pra quem gosta de ver os erros ainda em tempo de compilação.[/quote]
Pois é, justamente por ser type safe, não considerava duck typing.
Mas isso tinha a ver com minha opinião pessoal sobre o conceito. Só considerava duck typing quando a resolução era feita em runtime.
Aliás, particulamente, sou um desses que “gosta de ver os erros ainda em tempo de compilação”…
Uma fonte de erro a menos para se preocupar em runtime (para mim já basta as regras de negócio mal definidas).
[quote=PedroTOliveira][quote=renzonuccitelli]Por isso eu acho o duck typing fantástico. Em outra linguagens, como Python, Ruby e escala, vc simplesmente passa a chamar o método e implementa só para as classes que precisarem, podendo executar um método default para as classes que não implementem o método.
Mas como o Fórum é de Java…rs[/quote]
Isso se chama Herança e Polimorfismo no Java.
Edit: Apesar de não ter o caráter dinâmico dessas linguagens é possível fazer com uma boa modelagem orientada a objetos.
Eu acho o Duck Typing bem ágil, porem o uso excessivo dele pode denotar um modelo OO ruim! [/quote]]
O problema do Java é que vc só faz polimorfismo com herança. Inclusive qdo eu só sabia Java, achava que isso era universal. Inclusive em Java eu só uso Herança se for fazer poliforfismo. Caso contrário, só uso composição via injeção de dependência, para facilitar os testes.
[quote=AbelBueno][quote=renzonuccitelli] Duck Typing no Scala. Inclusive no Scala é type safety, muito bom pra quem gosta de ver os erros ainda em tempo de compilação.[/quote]
Pois é, justamente por ser type safe, não considerava duck typing.
Mas isso tinha a ver com minha opinião pessoal sobre o conceito. Só considerava duck typing quando a resolução era feita em runtime.
Aliás, particulamente, sou um desses que “gosta de ver os erros ainda em tempo de compilação”…
Uma fonte de erro a menos para se preocupar em runtime (para mim já basta as regras de negócio mal definidas).
[/quote]
Questão de gosto. Eu acho bom tipagem forte para programadores novos. Quando vc fica mais experiente, acho melhor uma linguagem que te das mais poder. Como diria o tio Ben: “Grande poderes trazem grande responsabilidades”…rs. Mas cada um na sua, ainda bem que temos infinitas ferramentas para escolher.
Acho que nem seria questão de dinamica versus estática. Scala é estática, mas pelo pouco que conheço, acho bem melhor que Java. Menos verboso, tem closure, duck typing. Mas enfim, questão de gosto, e contra gosto, não há argumentos
[quote=renzonuccitelli]
O problema do Java é que vc só faz polimorfismo com herança. Inclusive qdo eu só sabia Java, achava que isso era universal. Inclusive em Java eu só uso Herança se for fazer poliforfismo. Caso contrário, só uso composição via injeção de dependência, para facilitar os testes.
[]s[/quote]
Bom eu sempre tive a o polimofismo na Orientação a Objetos como uma característica inerente a Herança já que prevê sobrecarga e a generalização de tipos.
Jamais interpretei interfaces como objetos do mesmo tipo das implementações, são objetos que podem sim ter comportamentos parecidos mas que não deveriam ser considerados do mesmo tipo. Diria que estão mais para objetos que se comunicam através de contratos semelhantes do que a mesma coisa.
Duck Typing ao meu ver se parece com Herança Múltipla, eu digo que fulano é do tipo ser Humano mas se ele se comporta como um Macaco então ele também pode ser um Macaco.
Nada impede de você fazer:
A verdade que isso 'e uma questao de gosto e modelo.
Não entendi a colocação. Interface pra mim é uma classe abstrata que não permite definir métodos concretos nem atributos. Inclusive, a nível de JVM, interface é uma classe abstrata.
Acho que não tem nada ver com herança múltipla. Quando a classe é dinamica, a sua interface está presenta na própria classe. Vc não precisa criar o contrato explicitamente (criando um interface). Vc simplesmente parte do pressuposto que os objetos que quiser usar implementam o contrato, o pode até mesmo inserir um comportamente default caso o objeto não cumpra o contrato. Assim vc tem o poder de fazer como kiser, e não ser obrigado a codificar de uma forma imposta pela linguagem.
[quote]Nada impede de você fazer:
A verdade que isso 'e uma questao de gosto e modelo.[/quote]
Nada impede. Mas aí vc tem que implementar os métodos da interface obrigatoriamete. mas digamos que MonkeyAction tenha o método comer(). Aí vc escreve um método que quer usar um método comer, só que de uma interface FungoActions. ai vc vai na sua classe fulano, e tem que declarar essa interface, coisa que não seria necessário com DuckTyping. E o pior, quando vc usa um RMI da vida, tem que importar as interfaces do lado cliente e servidor.
Mas enfim, gosto e gosto…rs
Feliz Ano Novo pra todo mundo, vou pegar estrada. Até ano que vem…rs
Tá você pode tratar dessa forma, basta entender quando você diz que você está implementando a sua abstração você precisa dizer o que ela faz ok?
Agora se você diz que está extendendo algo, é porque você pretende Classificar aquela abstração de uma forma mais específica ok?
Sendo assim:
Você pode ter um tipo genérico com comportamentos definidos ou não e ter filhos com outros comportamentos herdados e sobre-escritos (AbstractCollection -> AbstractList, AbstractCollection -> AbstractSet) e pode ter comportamentos específicos implemenmtados por intefaces (List, Set).
Por isso existem Classes Abstratas e Interfaces??
Cara as API OO são feitas para isso também, se eu herdo uma classe eu tenho o poder de sobre-escrever um método.
O que eu não sobre-ecrever eu posso utilizar o comportamento padrão.
Isso não tem haver com tipagem dinâmica ou não. Para mim isso continua sendo Herança simples.
Uma vez que em Java só permite herança multipla através de interfaces, muitas vezes vc não poderá definir o comportamento padrão da classe. No mínimo, terá que fazer uma composição e delegar a implementação para outra classe. Mas enfim, eu entendo completamente o que vc escreveu. Para mim foi muito bom aprender outras tecnologias e paradigmas, se vc e outros acham que que Java é onde são mais produtivos e estão felizes com ela, então blz. Como já disse, ainda bem que temos várias opções para todos os gostos
Já passei por esse problema ao criar o meu TCC.
Meu TCC foi sobre IA no xadrez e tive que criar uma modelagem de cada peça.
Para se resolver esse problema o melhor Design Pattern é o Strategy.
Dá uma olhada no Head First Design Pattern Cap 1. Lá explica detalhadamente tal pattern.
Praticamente ele utiliza composição utilizando interfaces, e isso facilita para que aconteça
transições de tipos de peças dinamicamente. :lol:
Engraçado ninguém ter sugerido que o autor do tópico criasse uma interface específica para o método de captura, já que o mesmo não se aplica a todas as Peças. Aliás, Peça me parece uma interface sem muita coesão. Eu usaria interfaces que expressam comportamentos: movimento, captura, etc.