To avoid the antontron singleton and to avoid defining the list as static final
, what you can do is design your application so that a class, let's call it FuenteDatos
, contains your list and all the classes that need to access this list must receive an instance of FuenteDatos
as argument in the constructor to work. This is called composition ratio: the dependency between the classes and FuenteDatos
is a strong dependence, without an instance of that kind the others can not work.
The design would be similar to this:
public class FuenteDatos {
private List<Dato> listaDatos = new ArrayList<>();
public boolean agregar(Dato dato) {
return listaDatos.add(dato);
}
//por poner un ejemplo
public Dato buscar(int id) {
Optional<Dato> dato = listaDatos.stream().filter(d -> d.id == id).findFirst();
return dato.isPresent() ? dato.get() : null;
}
public void paraTodos(Consumer<Dato> funcionParaTodos) {
listaDatos.forEach(funcionParaTodos);
}
}
And then in the classes that need it:
//de acuerdo a tu descripción del problema
public class Almacen {
private FuenteDatos fuenteDatos;
public Almacen(FuenteDatos fuenteDatos) {
this.fuenteDatos = fuenteDatos;
}
public void operacionX(Dato dato) {
if (<reglas para validar dato) {
fuenteDatos.agregar(dato);
}
}
public void mostrarDatosEnConsola() {
fuenteDatos.paraTodos(d -> System.out.println(
String.format("Dato. Id: %d, Nombre: %s", d.getId(), d.getNombre())
));
}
}
And from your main class orchestras the integration of all these components:
public class Principal {
public static void main(String[] args) {
//aquí creamos la instancia de FuenteDatos
FuenteDatos fuenteDatos = new FuenteDatos();
//aquí creamos la instancia de Almacen
//y la asociamos a FuenteDatos
Almacen almacen = new Almacen(fuenteDatos);
//puedes iniciar más clases necesarias para que funcione tu aplicación aquí
//...
//y que comience tu aplicación
System.out.println("Bienvenido al Almacén.");
//resto del código...
}
}