Evite ligação estática em operações que usam argumentos de hierarquia
Eu encontrei um problema sobre ligação estática.
Minha classe real é muito extensa, então usarei várias aulas de brinquedo para expressar meu problema.
Supomos que temos a seguinte hierarquia.
public class Element{}
public class Element1 extends Element{}
public class Element2 extends Element{}
eu tenho umStock
classe que usa os diferentesElement
especialização definida porElement
hierarquia.
public class Stock{
public void operation(Element1 e1){
System.out.println("Operation - " + e1.getClass().getName());
}
public void operation(Element2 e2){
System.out.println("Operation - " + e2.getClass().getName());
}
}
Finalmente, eu tenho umStockManager
que permite gerenciar umStock
.
public StockManager{
Stock stock;
public StockManager(Stock stock){
this.stock=stock;
}
public void manage(List<Element> elements){
for(Element element: elements){
stock.operation(element);
}
}
}
Obviamente, esse código não compila, porqueStock
não define um método que inclua umElement
como argumento. Nesse caso, podemos corrigir o código usando diferentes abordagens.
Primeiro, poderei definir um método que definirá umElement
como argumento de entrada, p.
public void operation(Element e){
System.out.println("Operation - " + e.getClass().getName());
}
Esse método pode definir uma opção para gerenciar os diferentes elementos concretos (Element1
, Element2
) No entanto, isso é impossível para mim, porque a opção viola oAbrir / Fechar Princípio, e eu tenho muitos elementos concretos.
Outra alternativa, eu poderia usar algo como oPadrão do visitante. Eu poderia enviar oStock
objeto a um elemento concreto. E o elemento concreto será encarregado de usar oStock
operações. Portanto, a classe pode mudar para:
public abstract class Element{
public abstract void stockOperation(Stock stock);
}
public class Element1 extends Element{
public abstract void stockOperation(Stock stock){
stock.operation(this);
}
}
public class Element2 extends Element{
public abstract void stockOperation(Stock stock){
stock.operation(this);
}
}
E aStockManager
.
public StockManager{
Stock stock;
public StockManager(Stock stock){
this.stock=stock;
}
public void manage(List<Element> elements){
for(Element element: elements){
element.stockOperation(stock);
}
}
}
Permite determinar em tempo de compilação o tipo estático dos elementos de concreto. E a ligação dinâmica será responsável por chamar ostockOperation
método do elemento concreto correto (Element1
ouElement2
) NO ENTANTO !!, tenho código duplicado nos elementos concretos e terei vários elementos concretos.
Portanto, gostaria de saber se conhecemos algum design de padrão ou alguma prática recomendada para resolver esse problema. (Outra alternativa, talvez seja usar reflexão, mas eu não gostaria de usá-la).