2012-07-27 11 views
6

Ich habe bereits eine Menge existierender Daten in meiner Datenbank und möchte einen Punktemechanismus entwickeln, der für jeden Benutzer eine Punktzahl basierend auf seinen Aktionen berechnet.Entwerfen eines Punktsystems im Frühjahr

Ich implementiere diese Funktionalität in einer pluggable Weise, so dass sie unabhängig von der Hauptlogik ist und auf Frühlingsereignissen basiert, die gesendet werden, sobald eine Entität geändert wird.

Das Problem ist, was mit den vorhandenen Daten zu tun ist. Ich möchte ab jetzt keine Punkte sammeln, sondern alle Daten bis jetzt einbeziehen.

Was ist der praktischste Weg, dies zu tun? Soll ich meine Plugins so gestalten, dass eine index() -Methode verwendet wird, die mein System dazu zwingt, jede einzelne Entität von der Datenbank abzurufen, sende ein EntityDirtyEvent, feuere die Punkte-Plugins für jedes und aktualisiere es dann es, um Punkte neben jeder Entität gespeichert zu lassen. Das könnte viel Overhead zur Folge haben, oder?

Die einfachste Sache wäre, eine komplexe gespeicherte Prozedur zu erstellen, und dann die index() -Aufruf die gespeicherte Prozedur aufrufen. Das scheint mir aber auch schlecht zu sein. Da ich sowieso die Logik für die Berechnung der Punkte in Java schreiben muss, warum sollte es dann wieder in SQL sein? Außerdem bin ich im Allgemeinen kein Fan der Aufteilung der Geschäftslogik in die verschiedenen Schichten.

Hat jemand das schon mal gemacht? Bitte helfen Sie.

Antwort

4

Zuerst unterscheiden wir zwischen der Implementierungsstrategie und Geschäftsregeln.

Da Sie bereits über die Daten verfügen, sollten Sie in Erwägung ziehen, Ergebnisse direkt aus den Daten zu erhalten. Dies bildet das Datendomänenmodell. Entwerfen Sie das Datenmodell, um alle Ihre Daten zu speichern. Erstellen Sie anschließend eine Reihe von Abfragen, Ansichten und gespeicherten Prozeduren, um auf die Daten zuzugreifen und sie zu aktualisieren.

Sobald Sie diese Ansichten haben, verwenden Sie eine Datenzugriffsbibliothek wie die Spring JDBC-Vorlage, um diese Daten abzurufen und sie in Java-Objekte (Listen, Karten, Personen, Punkttabellen usw.) darzustellen.

Was Sie bisher erreicht haben, ändert sich nicht viel, unabhängig davon, was in den oberen Schichten des Systems passiert. Dies nennt man Modell.

Entwickeln Sie dann eine Regelbasis- oder Logikimplementierung, die unter welchen Eingaben Benutzeraktionen, Datenbedingungen oder für alle anderen Bedingungen bestimmen, welche Daten benötigt werden. Im mathematischen Sinne ist dies wie eine Matrix. Im Sinne der Programmierung wäre dies eine Menge von logischen Aussagen. Wenn dies und das und das wahr ist, dann hole diese Daten, sonst bekommst du diese Daten usw. Das umfasst die Logik in deinem System. Daher wird es "Controller" genannt.

Verschieben Sie diese Logik nicht in die Abfragen/gespeicherten Prozeduren/Sichten.

Dann endlich ein Frontend oder "Konsole" dafür entwickeln. Entwickeln Sie im einfachsten Fall ein Konsolen-Eingabesystem, das eine .. und eine Reihe von Ergebnissen anzeigt. Dies ist Ihre "Sicht" auf das System.

Sie können die Ansicht schließlich in eine Webanwendung entwickeln. Die obige Befehlszeilenansicht kann weiterhin in Form eines Restful-API-Servers ausgeführt werden.

2

Ich denke, es gibt ein Problem hier zu berücksichtigen: Wie ich verstehe, gibt es riesige Daten in der Datenbank, so dass die Idee, nur einen Mechanismus zur Berechnung des Punktsystems zu erstellen, nicht der beste Ansatz sein könnte.

In der Tat, wenn Sie nicht sammeln wollen Punkte sammeln, sondern alle Daten enthalten, müssen Sie die Informationen verarbeiten und berechnen, die Sie jetzt haben. Ja, wenn Sie das erste Mal ausführen, kann dies zu einem Overhead führen, aber wie Sie gesagt haben, müssen diese Daten berechnet werden.

Auf der anderen Seite können Sie einen anderen Mechanismus hinzufügen, der Änderungen in einer Entität berücksichtigt und einen anderen Prozess startet, der in der Lage ist, die neue Zeigedifferenz zu berechnen, die für diese bestimmte Modifikation gilt.

So können Sie einen Dienst verwenden, der verantwortlich für die Berechnung des Zeige-System, eines für eine einzelne Entität und andere, kann länger sein zu beenden, in der Lage, die globalen Punkte zu berechnen. Selbst wenn Sie nicht in Echtzeit berechnet werden müssen, können Sie einen geplanten Job erstellen, der für den Start verantwortlich ist.

Schließlich, ich weiß, es ist nicht ein guter Ansatz, um die Geschäftslogik in zwei Schichten (Db + Java) zu spalten, aber manchmal ist eine Anforderung, tut es, zum Beispiel, wenn Sie schnell auf eine Anfrage antworten müssen, die schließlich arbeitet mit viele Register. Ich habe einige Fälle gefunden, in denen es keine andere Möglichkeit gibt, der Datenbank Geschäftslogik hinzuzufügen (als gespeicherte Prozeduren usw.), um viele Daten zu verwalten und das Endergebnis an den Browser-Client zurückzugeben (zB: Berechnungsprozess zu einer bestimmten Zeit)).

2

Sie versuchen, "Bootstrapping" zu erreichen. Der gewählte Ansatz sollte davon abhängen, wie kompliziert die Punktberechnungen sind. Wenn gespeicherte Prozeduren oder einfache Aktualisierungsanweisungen die einfachste Lösung sind, tun Sie dies.

Wenn die Berechnungen kompliziert sind, schreiben Sie einen Stapeljob, der Ihre vorhandenen Daten lädt, wahrscheinlich die älteste zuerst anordnet und die Ereignisse entsprechend diesen Daten auslöst, als wären sie gerade passiert. Der Code, der sich auf ein Ereignis bezieht, sollte genau der gleiche Code sein, der sich auf ein zukünftiges Ereignis bezieht, sodass Sie keinen zusätzlichen Code außer den Batch-Jobs selbst schreiben müssen.

Da Sie dieses Ding nur einmal ausführen, gehen Sie mit der einfachsten Lösung, auch wenn es schnell und schmutzig ist.

2

Sie scheinen in die richtige Richtung zu gehen. Sie wissen, dass Sie Ihre "Punkte" -Ding von der Hauptanwendung abgekoppelt haben wollen. Da dies impliziert, dass Sie bereits den Ruhezustand verwenden (durch das Tag!), Können Sie auf das Hibernate-Ereignissystem tippen (siehe Abschnitt 14.2). Abhängig von der Größe/Komplexität Ihres Systems können Sie hier Ihre Punkterechnungen plugintieren (wenn es kein großes/komplexes System ist), oder Sie können Ihr eigenes Ereignis veröffentlichen, um von der Software, die gerade zuhört, aufgenommen zu werden.

Der Punkt in beiden Design-Ansatz ist, dass weder weiß noch kümmert sich um Ihre Punkt Berechnungen. Wenn Sie, wie ich vermute, versuchen, einen ziemlich allgemeinen Plugin-Mechanismus zu erstellen, dann veröffentlichen Sie Ihre eigenen Events von diesem Verbindungspunkt aus auf diesem System. Wenn Sie dann keine Plug-Ins für eine bestimmte Installation/Einrichtung haben, dann werden die Ereignisse von niemandem abgerufen/verarbeitet. Wenn Sie mehrere Plug-Ins für eine andere Installation/Einrichtung haben, können sie je nach dem empfangenen Ereignis entscheiden, welche Verarbeitung sie durchführen müssen. Im Falle des "Punkte-Plugins" würde es seinen Punktwert berechnen und speichern. Kein gespeicherter Prozess erforderlich ....

1

Es gibt zwei verschiedene Möglichkeiten. Eines ist Ihnen bereits bekannt - Abfrage der Datenbank nach geänderten Daten. In diesem Fall treffen Sie die Datenbank, wenn keine Änderungen vorgenommen werden. Dies kann Ihren Prozess verlangsamen.

Zweiter Ansatz - Wenn Änderungen in der Datenbank auftreten, löst die Datenbank das Ereignis aus. Sie können CDC (Change Data Capture) verwenden. Es wird den Overhead minimieren.

Sie können weitere Optionen in Spring Integration

suchen