Por lo general, logro un bajo acoplamiento creando clases que intercambian listas, conjuntos y mapas entre ellos. Ahora estoy desarrollando una aplicación por lotes Java y no puedo poner todos los datos dentro de una estructura de datos porque no hay suficiente memoria. Tengo que leer y procesar un fragmento de datos y luego pasar al siguiente. Entonces, tener un acoplamiento bajo es mucho más difícil porque tengo que verificar en algún lugar si todavía hay datos para leer, etc.
Lo que estoy usando ahora es:
Fuente -> Proceso -> Persistir
Las clases que procesan tienen que preguntar a las clases de origen si hay más filas para leer.
¿Cuáles son las mejores prácticas y / o patrones útiles en tales situaciones?
Espero poder explicarme, si no me lo cuentas.
fuente
Respuestas:
De los comentarios veo que estás usando Java. Eche un vistazo a varias implementaciones de cola . Particularmente, BlockingQueue es útil para escenarios productor-consumidor . Podría tener dos colas: una entre Fuente (productor de datos) y Proceso (consumidor de datos), y otra entre Proceso (productor de resultados) y Persistir (consumidor de resultados).
Con colas de bloqueo de capacidad limitada, es bastante fácil implementar sistemas eficientes (la parte del cuello de botella, sea lo que sea, se mantiene alimentada con datos el 100% del tiempo), y aún usa solo una cantidad limitada de memoria, sin importar cuántos datos haya.
fuente
Una cola de bloqueo (de Joonas Pulakka) es la respuesta pesada. Una respuesta más simple podría funcionar. Si tiene todos los datos almacenados en la fuente, simplemente puede pasar una referencia al procesador, y puede obtener los datos de la fuente. Por supuesto, esto es probablemente lo que estabas haciendo en el pasado. Es posible que no tenga todos los datos en la memoria en la fuente y que no obtenga el bajo acoplamiento que desea.
El siguiente paso sería utilizar una interfaz Enumerator o Iterator. (Los iteradores son más comunes en Java, aunque la mayoría de las veces ese
remove
método es solo una molestia). El procesador obtendría el iterador de la fuente y luego llamaría a los métodos hasta que esté listo. Si la fuente extrae datos de terrabytes de alguna parte, cada llamada puede demorar un poco. Pero si va a dormir el procesador hasta que haya algo en la cola de todos modos, esto lo hará automáticamente. Y si la fuente se adelanta al productor, la fuente esperará automáticamente a que el productor llamehasNext
ynext
.Si, por otro lado, desea que la fuente tome datos de su fuente lo más rápido posible y los acumule hasta que el procesador se ponga al día, sin esperar a que el procesador procese, entonces la cola, y múltiples hilos, comienza a parecer una buena idea, aunque más complicada. Ahora, la fuente se acumulan los datos cuando se puede correr más rápido (el límite es de suponer algo así como disco I / O), y el procesador puede reducir el tamaño de la pila cuando se puede correr más rápido, (su límite es la rapidez con la persistencia módulo puede persistir los datos).
fuente