Evite el enlace estático en operaciones que usan argumentos de jerarquía

He encontrado un problema sobre el enlace estático.

Mi clase real es muy extensa, por lo que utilizaré varias clases de juguetes para expresar mi problema.

Suponemos que tenemos la siguiente jerarquía.

public class Element{}

public class Element1 extends Element{}

public class Element2 extends Element{}

tengo unStock clase que usa los diferentesElement especialización definida porElement jerarquía.

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 tengo unStockManager lo que permite gestionar unStock.

public StockManager{

    Stock stock;
    public StockManager(Stock stock){
        this.stock=stock;
    }

    public void manage(List<Element> elements){
        for(Element element: elements){
            stock.operation(element);
        }
    }
}

Por supuesto, este código no se compila, porqueStock no define un método que incluya unElement como argumento En este caso podríamos arreglar el código usando diferentes enfoques.

Primero, podré definir un método que definirá unElement como argumento de entrada, p.

public void operation(Element e){
    System.out.println("Operation - " + e.getClass().getName());
}

Este método podría definir un interruptor para administrar los diferentes elementos concretos (Element1, Element2) Sin embargo, esto es imposible para mí, porque el interruptor viola elPrincipio de apertura / cierre, y tengo muchos (muchos) elementos concretos.

Otra alternativa, podría usar algo como elPatrón de visitante. Podría enviar elStock objetar a un elemento concreto. Y el elemento concreto se encargará de usar elStock operaciones Entonces, la clase podría cambiar a:

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);
    }
}

Y elStockManager.

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 en tiempo de compilación el tipo estático de los elementos concretos. Y el enlace dinámico se encargará de llamar alstockOperation método del elemento concreto correcto (Element1 oElement2) SIN EMBARGO !!, tengo código duplicado en los elementos concretos, y tendré varios elementos concretos.

Por lo tanto, me gustaría saber si conocemos algún diseño de patrón o alguna práctica recomendada para resolver este problema. (Otra alternativa, tal vez sea usar la reflexión, pero no me gustaría usarla).

Respuestas a la pregunta(1)

Su respuesta a la pregunta