Padrão Strategy: métodos da interface nas classes filhas

Tenho uma interface, e duas classes que a implementam… o problema é que o método, implementado da interface, para cada filha devem retornar tipos diferentes, isto é, uma filha deve utilizar o método mas retornar uma string e outra filha deve utilizar o mesmo método mas retornar um inteiro.

Como faço nessa situação?

Você pode usar um código como abaixo para fazer o que você quer:

interface SuaInterface {
    Object meuMetodo();
}

class SuaFilhaInt implements SuaInterface {

    @Override
    public Integer meuMetodo() {
        return 0;
    }
    
}

class SuaFilhaString implements SuaInterface {

    @Override
    public String meuMetodo() {
        return "";
    }
    
}

A interface declara um tipo mais geral e as filhas implementando os métodos definem um tipo de retorno mais específico.

O problema é que trabalhar com inteiros e strings são duas coisas totalmente diferentes.

O que adianta ter a interface, se o código precisará saber com que tipo de implementação (classe filha) está lidando?

Então AbelBueno, essa era minha dúvida, porque segundo o Padrão Strategy, devemos encapsular os algoritmos e criar uma interface com os métodos comuns para as filhas. Me deparei com esta situação no trabalho, o mesmo método deveria retornar um int para um caso e um string para outro caso, coisas totalmente diferentes, mas as regras de negócio aqui deveria ser desta maneira. Aí pensei, para que eu declarar uma interface? Cada filha precisará saber o que retornar… então aí manter a interface é simplesmente para dizer que estou dentro do Padrão Strategy? Só por plus? Ou manter esta interface tem alguma importância maior?

Alguém saberia me responder a pergunta acima?

É padrão strategy sim eu agora vejo 3 opções:

  1. usar um retorno polimórfico…vc pode criar uma interface sua para isso.
  2. tentar usar generic
  3. usar um retorno de classe usando o padrão wrapper que guarda um tipo com generic. Aqui vc sempre retorna essa wrapper com um valor GENERICO
    Eu escolheria a 3.
    T+

A idéia do strategy é poder inserir um algoritmo diferente para realizar a mesma coisa de diversas formas…
Em resumo, isso evita algunfs ifs, melhora a manuntenção do código…

No seu caso, no retorno desse método você já colocaria um if pra saber se é inteiro ou se é string.

Talvez você deva refatorar a classe que recebe a implementação para delegar mais trabalho para o algoritmo inejtado
De forma que você possa usar a interface de forma uniforme.

[quote=AbelBueno]Talvez você deva refatorar a classe que recebe a implementação para delegar mais trabalho para o algoritmo inejtado
De forma que você possa usar a interface de forma uniforme.[/quote]
É justamente as opções das minhas dicas…

Desculpe FernandoFranzini, talvez não tenha entendido sua sugestão.

Eu pensei que estava falando de mudar o tipo de retorno do método.

Eu falei para transferir o código que usa esse retorno para fora da classe também.

Vou tentar um retorno genérico.
Mas meio redundante, né?!

Desculpe FernandoFranzini, talvez não tenha entendido sua sugestão.

Eu pensei que estava falando de mudar o tipo de retorno do método.

Eu falei para transferir o código que usa esse retorno para fora da classe também.[/quote]

Mas tratar este retorno por fora? Não vai sair do padrão strategy? Se bem que é uma boa opção quando tenho que retornar objetos filhos que estão em outras estruturas hierarquicas.

Imagina essa mesma situação, porém ao invés de o retorno ser uma string e um int, eu ter que retornar um objeto PessoaFisica e um objeto PessoaJuridica, ambos herdados de um objeto Pessoa.

Acho que aí ficou bem complexo heim?

Não pq seu cenários vai alem do patter

Tudo bem…eu ainda prefiro wrapper…

Claro…seu cenário vai bem alem de 1 padrão…dai vc pode aplicar padrões compostos…

Você pode postar um exemplo dessa sua interface?

Por mim, se o retorno é diferente, ele não atende a interface, não é um caso de Strategy. Ou então, há como reescrever de maneira que isso fique indiferente.

[code]class Wrapper<T> {
private T objeto;

public Wrapper(T o) {
	objeto = o;
}

public T getObjeto() {
	return objeto;
}

}

interface SuaInterface<T> {
Wrapper<T> meuMetodo();
}

class SuaFilhaInt implements SuaInterface<Integer> {

@Override
public Wrapper&lt;Integer&gt; meuMetodo() {
	return new Wrapper&lt;Integer&gt;(0);
}

}

class SuaFilhaString implements SuaInterface<String> {

@Override
public Wrapper&lt;String&gt; meuMetodo() {
	return new Wrapper&lt;String&gt;("Sua String");
}

}[/code]

É isso mesmo que o Fernando escreveu, ficou ótimo o código, e atende ao padrão Strategy. Vou utiliza-lo. Obrigadão garoto! Depois pago uma rodada de cerveja pra nóis!!

Na verdade Vini, o caso é o que eu citei acima, não tenho código ainda, estou fazendo a UML do projeto e percebi que o mesmo método implementado nas filhas deveriam retornar objetos diferentes, aí gostaria de saber da comunidade GUJ qual a melhor forma de resolver esse problema, porque quando implementamos uma interface, tenho que obrigatoriamente utilizar aquele método e retorna o objeto que a interface me impõe, só que segundo as regras de negócio aqui, os métodos devem retornar objetos diferentes… então pensei… será que vou ter que tirar a interface e copiar e colar o método em tudo quanto é “classe que seriam filhas”? Sairia fora do padrão! Tem N maneiras de escrever esse problema… mas gostaria da melhor forma, segundo o Strategy.

Muitas vezes basta retornar o objeto da superclasse. Você até pode retornar um filho dele em cada Strategy graças a existência de covariant result types.

Agora, se sua modelagem está retornando tipos não relacionados, aí olhe bem seu design. Provavelmente tem falha aí.

[quote=ViniGodoy]Muitas vezes basta retornar o objeto da superclasse. Você até pode retornar um filho dele em cada Strategy graças a existência de covariant result types.

Agora, se sua modelagem está retornando tipos não relacionados, aí olhe bem seu design. Provavelmente tem falha aí.[/quote]

Vini teria algum exemplo desse “covariant result types”?

Sorry, o nome correto é covariant return types.
Durante uma sobrescrita, você pode retornar um objeto que seja filho do objeto do pai.