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).

questionAnswers(1)

yourAnswerToTheQuestion