Normalerweise erreiche ich eine niedrige Kopplung, indem ich Klassen erstelle, die Listen, Mengen und Karten zwischen ihnen austauschen. Jetzt entwickle ich eine Java-Batch-Anwendung und kann nicht alle Daten in eine Datenstruktur einfügen, da nicht genügend Speicher vorhanden ist. Ich muss einen Datenblock lesen und verarbeiten und dann zum nächsten übergehen. Eine niedrige Kopplung ist also viel schwieriger, da ich irgendwo prüfen muss, ob noch Daten zu lesen sind usw.
Was ich jetzt benutze ist:
Quelle -> Prozess -> Bestehen
Die Klassen, die verarbeitet werden, müssen die Quellklassen fragen, ob mehr Zeilen zu lesen sind.
Was sind die besten Praktiken und / oder nützlichen Muster in solchen Situationen?
Ich hoffe ich erkläre mich, wenn nicht sag es mir.
quelle
Antworten:
Aus den Kommentaren geht hervor, dass Sie Java verwenden. Schauen Sie sich verschiedene Queue- Implementierungen an. Insbesondere Blocking ist für nützliche Producer-Consumer - Szenarien. Sie können zwei Warteschlangen haben: eine zwischen Source (Datenproduzent) und Process (Datenkonsument) und eine zwischen Process (Ergebnisproduzent) und Persist (Ergebniskonsument).
Mit Blockierungswarteschlangen mit begrenzter Kapazität ist es ziemlich einfach, effiziente Systeme zu implementieren (der Engpass wird zu 100% mit Daten versorgt), wobei immer noch nur eine begrenzte Menge an Speicher verwendet wird, unabhängig davon, wie viele Daten vorhanden sind.
quelle
Eine blockierende Warteschlange (von Joonas Pulakka) ist die schwere Antwort. Eine einfachere Antwort könnte funktionieren. Wenn Sie alle Daten in der Quelle gespeichert haben, können Sie einfach einen Verweis an den Prozessor übergeben und die Daten einfach aus der Quelle abrufen. Natürlich ist dies wahrscheinlich das, was Sie in der Vergangenheit getan haben. Möglicherweise befinden sich nicht alle Daten im Speicher der Quelle, und Sie erhalten möglicherweise nicht die gewünschte niedrige Kopplung.
Der nächste Schritt wäre die Verwendung einer Enumerator- oder Iterator-Schnittstelle. (Iteratoren sind in Java häufiger anzutreffen, obwohl diese
remove
Methode meistens nur eine Nusance ist.) Der Prozessor bezieht den Iterator von der Quelle und ruft die Methoden dann auf, bis er fertig ist. Wenn die Quelle Terrabyte an Daten von irgendwoher bezieht, kann jeder Anruf eine Weile dauern. Wenn Sie den Prozessor jedoch in den Ruhezustand versetzen, bis sich ohnehin etwas in der Warteschlange befindet, wird dies automatisch ausgeführt. Und wenn die Quelle dem Produzenten voraus ist, wartet die Quelle automatisch darauf, dass der Produzent anrufthasNext
undnext
.Wenn Sie andererseits möchten, dass die Quelle Daten so schnell wie möglich von ihrer Quelle abruft und sie bevorratet, bis der Prozessor aufholt und nicht darauf wartet, dass der Prozessor verarbeitet wird, dann die Warteschlange - und mehrere Threads - beginnen, wie eine gute, wenn auch kompliziertere Idee auszusehen. Jetzt kann die Quelle die Daten stapeln, wenn sie schneller ausgeführt werden können (ihre Grenze liegt vermutlich bei Festplatten-E / A), und der Prozessor kann die Größe der Stapel reduzieren, wenn sie schneller ausgeführt werden kann (ihre Grenze ist die Geschwindigkeit der Beständigkeit) Modul kann die Daten beibehalten).
quelle