PHP DataMapper mit mehreren Persistenz-Layern

8

Ich schreibe ein System in PHP, das auf drei Persistenzebenen schreiben muss:

  • Ein Webdienst
  • Zwei Datenbanken (eine mysql one mssql)

Der Grund dafür sind Legacy-Systeme, die nicht geändert werden können.

Ich möchte das DataMapper-Muster verwenden und versuche, den besten Weg zu finden, um das zu erreichen, was ich möchte. Ich habe eine Schnittstelle wie folgt:

%Vor%

Im Folgenden finden Sie einen kurz vorstellten und gekürzten Code:

%Vor%

Meine Frage ist, dass es, da es drei Persistenzschichten gibt, wahrscheinlich auch drei Mapper für jede benötigen werden. Ich hätte gerne eine clean design pattern inspirierte Schnittstelle, um das zu schaffen.

Ich sehe es als drei Optionen:

  1. Injizieren Sie drei Mapper in den Service und rufen Sie create auf jedem
  2. auf
  3. $ _ mapper ist ein Array / eine Sammlung und iteriert durch sie und ruft create auf jedem
  4. auf
  5. $ _ mapper ist eigentlich ein Containerobjekt, das als a fungiert Weitere Proxy und Anrufe erstellen auf jedem

Etwas stimmt mich mit jeder dieser Lösungen falsch und würde jedes Rückgespräch / anerkannte Entwurfsmuster schätzen, die dieses passen könnten.

    
John Royal 25.10.2012, 08:07
quelle

3 Antworten

2

Ich musste ein ähnliches Problem lösen, aber vor vielen Jahren in der Zeit von PEAR DB. In diesem speziellen Fall mussten die Daten über mehrere Datenbanken hinweg repliziert werden.

Wir hatten nicht das Problem, dass die verschiedenen Datenbanken unterschiedliche Mappings haben, also war es ein bisschen einfacher.

Was wir getan haben, war die Fassade der DB-Klasse und überschreiben die Funktion getResult (oder was auch immer es genannt wurde). Diese Funktion analysierte dann das SQL und ob es ein Lesevorgang war - es würde es an nur einen gesicherten senden und wenn es ein Schreibvorgang wäre, würde es es an alle senden.

Dies funktionierte wirklich sehr gut für eine sehr stark ausgelastete Seite.

Vor diesem Hintergrund würde ich vorschlagen, alle Persistenzoperationen vollständig zu überdenken. Sobald Sie dies getan haben, sind die Implementierungsdetails weniger relevant und können jederzeit geändert werden.

Aus dieser Perspektive erscheinen alle Ihre Implementierungsideen als ein vernünftiger Ansatz. Es gibt jedoch verschiedene Dinge, über die Sie nachdenken sollten.

  • Was passiert, wenn eines der Backends einen Fehler erzeugt?
  • Welchen Leistungseinfluss hat das Schreiben auf drei Datenbankserver?
  • Können die Schreibvorgänge asynchron ausgeführt werden (wenn ja, stellen Sie die erste Frage erneut)

Es gibt möglicherweise auch einen anderen Weg, um dieses Problem zu lösen. Das heißt, gespeicherte Prozeduren zu verwenden. Wenn Sie einen primären Datenbankserver haben, könnten Sie einen Trigger schreiben, der beim Commit (oder ähnlichem) eine Verbindung mit der anderen Datenbank herstellt und die Daten synchronisiert.

Wenn die Datenaktualisierung nicht sofort erfolgen muss, könnten Sie die Primärdatenbank dazu veranlassen, Änderungen zu protokollieren und ein anderes Skript zu verwenden, das diese Daten regelmäßig in das andere System "einspeist". Auch hier muss das Problem der Fehler berücksichtigt werden.

Hoffe, das hilft.

    
drone.ah 24.02.2013 19:28
quelle
1

Zuerst ein bisschen Terminologie: Was Sie drei Schichten nennen, sind tatsächlich drei Module, keine Schichten. Das heißt, Sie haben drei Module innerhalb der Persistenzschicht.

Nun lautet die grundlegende Prämisse dieses Problems: Sie MÜSSEN drei verschiedene Persistenzlogiken haben, die drei verschiedenen Speicherquellen entsprechen. Dies ist etwas, das Sie nicht vermeiden können. Daher besteht die Frage nur darin, wie die Schreiboperation für diese Module aufgerufen wird (vorausgesetzt, dass Sie zum Lesen nicht alle drei aufrufen müssen, oder wenn Sie dies tun, ist dies eine separate Frage).

Von den drei Optionen, die Sie aufgelistet haben, ist meiner Meinung nach die erste besser. Denn das ist der einfachste der drei. Die anderen beiden müssen noch drei Module separat aufrufen, mit der zusätzlichen Aufgabe, einen Container oder eine Art Datenstruktur einzuführen. Sie können immer noch nicht vermeiden, drei Module irgendwo zu nennen.

Wenn Sie mit der ersten Option arbeiten, müssen Sie offensichtlich mit Schnittstellen arbeiten, um eine einheitliche Abstraktion für den Benutzer / Client (in diesem Fall den Dienst) zu gewährleisten.

Mein Punkt ist, dass: 1. Sie sind eine inhärente Komplexität in Ihrem Problem, die Sie nicht weiter vereinfachen können. 2. Die erste Option ist besser, weil die anderen beiden die Dinge komplexer und nicht einfach machen.

    
Nazar Merza 28.02.2013 17:39
quelle
0

Ich denke, Option # 2 ist meiner Meinung nach die beste. Ich würde damit gehen. Wenn Sie mehr als 10 Mapper als Option 3 hätten, wäre es sinnvoll, die Erstellungslogik an den Mapper selbst zu verschieben, aber da Sie eine vernünftige Anzahl von Mappern haben, ist es sinnvoller, sie einfach zu injizieren und über sie zu iterieren. Wenn Sie die Funktionalität durch Hinzufügen eines anderen Mappers erweitern möchten, müssen Sie nur noch eine Zeile zu Ihrer Abhängigkeitsinjektionskonfiguration hinzufügen.

    
Feras 27.02.2013 22:51
quelle

Tags und Links