mmofacts.com

OOP Klassendesign - Modulverwaltung

gepostet vor 16 Jahre, 2 Monate von Fobby

Hallo zusammen,

ich stoße immer wieder auf ein ähnliches Problem und würde dazu gern eure Meinungen / Erfahrungen hören. Als Beispiel werde ich typischerweise das Meerscheinchen wählen. Da mir die laufende Fussel so aber zu langweilig ist, mach ich ein Cyberschwei daraus ;)

Also ich habe das Objekt Cyberschwein, sowie CyberModule. Ein Cyberschwein kann mit beliebig vielen Modulen ausgestattet werden. Nachfahren der Module sind z.B. HealthModule, WeaponModule und DefenseModule.

Der generelle Ansatz ist nun, beim Auslesen des Schweinchens, alle zugehörigen Module auszulesen. Also mit einem Query die Module bestimmen und dann iterativ die Modulinstanzen generieren und dem Schweinsobjekt hinzufügen.

So weit, so gut. Habe ich jetzt aber 10 Schweine mit jeweils 50 Modulen, sind das 500 Queries (vorausgesetzt, 1 Modul kann mit einem Query vollständig generiert werden). Mit prepared Statements könnte man das zwar deutlich beschleunigen, allerdings ändert es nichts an der Unmenge an Queries, die nicht gesund sein kann.

Der logische Schritt scheint zu sein, alle Module eines Schweins auf einmal auszulesen. Doch wie stellt man das geschickt an, sodass noch eine schöne Klassenstruktur erhalten bleibt?

Ein weiteres Beispiel wären Items ("Cyberschwein") mit magischen Eigenschaften ("CyberModule") in einem Rollenspiel. Selbes Problem.

Freue mich auf eure Antworten/Anregungen :)

gepostet vor 16 Jahre, 2 Monate von Otteros

Ich weiß nicht, ob das jetzt so besonders sinnvoll ist, aber ich würde es folgendermassen machen:

EIne Klasse ModulQuery und die bekommt die Queryergebnisse  (alle für 1 Cyberschwein) und erstellt die ModulObjekte.

Jetzt musst du nurnoch das ModulQuery Objekt deinem Cyberschwein übergeben, was die Module dann einfach übernimmet.

Wer lusst hat kann das ganze in noch mehr Klassen zerlegen, aber vom Prinzip her wäre das eigtl. eine einfache Lösung, ohne die Klassenstrucktur zu zerstören.

gepostet vor 16 Jahre, 2 Monate von cherry

Ich glaube ich verstehe das Problem nicht ganz, denn fuer mich hoert es sich nach einem simplen 1:N mapping an und damit brauchst Du ein oder zwei Queries. Voraussetzung ist eine ausreichende Abstraktion der Module.

Die Frage ziehlt auf eine konkrete Implementierung ab, darum kann die Frage meiner Meinung nach so nicht beantwortet werden. Wir brauchen mehr Hintergrundinfos :-)

gepostet vor 16 Jahre, 2 Monate von Phoscur

Das ist interessant mit den Modulen, muss ich mal drüber nachdenken, aber meinen bisherigen Aufbau müsste ich dafür nicht groß umbauen.

Die Module habe alle Einträge in einer Tabelle? Dann wäre es wirklich sinnvoller nur ein Query für alle abzufeuern.

Das Konzept, das ich schon auf meinem Blog vorgestellt habe, musste ich nochmal ändern, werde das auch bald da wieder draufschreiben.

Ich nenne das, was du Cyberschwein nennst, Model. Zuerst hatte ich einen Ansatz, bei dem die Models ihre Queries selbst ausführen, aber da gabs quasi dein Problem. Zudem wollte ich das ganze zentral in der Session cachen, auch wenn man die meisten Objekte refreshen muss, bevor man sie wieder verwenden kann.

Ich habe jetzt pro Modeltyp einen Requester, der die Queries abfeuert. Dabei muss man ihm halt eine gut durchdachte "WHERE"-MySQL-Sequenz geben, teils könnte man auch oft verwendete Querymethoden im Requester speichern. Nun erstellt der Requester aus den Einträgen direkt Objekte, er füllt die Daten in die richtigen Models und verschachtelt diese (auf meinem Blog erstellt eig noch der DataHandler (für Sessions) die Objekte, aber das würde die Schleifenanzahl verdoppeln).

Die Requester werden durch den DataHandler (unique) aufgerufen, so erhält dieser direkt die Objekte um sie am Ende des Scriptes in der richtigen Reihenfolge zu zerstören bzw schlafen zu schicken (da muss man aufpassen, dass das auch wirklich geschieht, wahrscheinlich muss man extra den destruktor aufrufen, welcher eine flag abfragt, damit dies nicht doppelt geschieht.

Das Update mache ich übrigens durch einen Vergleich der anfangs abgefragten Daten und am Ende zurückgegebenen Daten (von den toten Models). Das funktioniert mit einem Query pro Tabelle ("CASE").

Gleich nochwas:

die Struktur:

1. SQL-SELECT

2. PHP Verarbeitung

3. SQL-UPDATE

ist anfällig für Race Conditions, auch dazu mehr auf meinem Blog.

Dagegen verwende ich in den Models auf oberster Ebene einen "used" Eintrag. Sollte man Schreibrechte auf ein Objekt wollen, muss man warten (eine MySQL-Prozedur tut das bei mir), bis der "used" Eintrag auf 0 steht.

Soviel bisher, bin zu einer Diskussion bereit :D

gepostet vor 16 Jahre, 2 Monate von TheUndeadable

Hart auf hart würde ich auch überlegen, ob du auf eine echt objektorientierte Datenbank aufsetzt, da die 'Relationierung' von objektorientierten Daten schon mal zu Problemen führen wird.

Dagegen verwende ich in den Models auf oberster Ebene einen "used" Eintrag. Sollte man Schreibrechte auf ein Objekt wollen, muss man warten (eine MySQL-Prozedur tut das bei mir), bis der "used" Eintrag auf 0 steht.

Transaktionen? LOCK TABLES?

gepostet vor 16 Jahre, 2 Monate von Phoscur

Unpräzise. Wieso die ganze DB sperren wenn du nur einen Eintrag werwendest? Bei 100 klickernden Usern?

gepostet vor 16 Jahre, 2 Monate von Kallisti

Du musst doch nur deine Struktur "umdrehen".

Weder Dein CyberSchwein, noch deine CyberModule pullen sich dann ihre Daten selbst aus der DB, sondern ein Codeabschnitt eine Logikebene (z.B. CyberBauernhof) darueber pullt alles in einem Query und instanziiert von dort aus alle Objekte.

Also im Endeffekt normales Factory-Pattern (wenn es universell sein soll)? Wahrscheinlich gibt es da wieder zig andere Buzzwords, die besser passen. ^^

gepostet vor 16 Jahre, 2 Monate von Phoscur

Jup, das ist ungefähr das was ich gemacht hab... Nur ohne Factories.. der Bauernhof heißt bei mir DataHandler, die Bauern da drauf Requester, die Schweine Model.

gepostet vor 16 Jahre, 2 Monate von knalli

Ich weiß jetzt nicht so ganz, ob ich das richtig verstanden habe @Op. Ich habe ein Schwein, und dort wird irgendwo definiert, welche Module benötigt/gebraucht werden? Das ganze dann hochskaliert im Beispiel mit 10 Schweinen a 50 Modulen.

Ganz anderer Ansatz/Idee: Cache

Was sprich dagegen, deinen eigentlichen Ansatz beizubehalten. Das Performance-Problem könnte man mit einem intelligenten Vorladen erledigen. Ich denke mal, ich habe das richtig verstanden, dass du nur die Metainformationen aus der Datenbank per Query benötigst? Sofern du das also weiterhin komplett dynamisch halten willst, würde ich eine (temporär, heap, alles möglich) Tabelle anlegen, wo nur Modul-braucht-Modul-Beziehungen stehen. Beim Laden von einem Modul werden alle (eventuell) gebrauchten Module geladen, die noch nicht bekannt sind (im Applikationscontext). Merkt deine Modulverwaltung, dass anschließend aber doch noch ein Modul fehlt (sei es durch ein Update oder am Anfang), so wird diese Beziehung in o.g. Tabelle eingetragen.

Dann hätte das zur Folge, dass du im Beispiel 10x Queries hast, die jeweils mehrere Ergebnisse zurückgeben. Hat Schwein #10 sogar Module, die genau so schon bekannt sind, muss gar nichts geladen werden. Ist die Verwaltung nur auf das eigene Modul beschränkt, entfällt das natürlich (selbstredend).

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Ich würde es relational so halt (wobei das keine bis ins letzte Detail durchdachte Lösung darstellen soll).

Eine Tabell mit deinen Klassen, wo auch das Cyberschwein zu finden ist. Dort werden die spefischen Sachen, wie Name und so gespeichert.

Dann noch eine Tabelle für die 1:n Beziehung von Cyberschwein:CyberModule (oder halt auch zu anderen Klassen).

Nun noch eine 3. Tabelle, welche 4 wichtige Spalten erhält. Die id der Klasse aus Tabelle 1. Die id des CyberModules und dann halt noch eine Spalte für einen Schlüssel und eine Spalte für den Wert.

Nun kannste alle Felder der ganzen Module für eine spezielle Klasse mit einmal auslesen oder halt auch modulspezifisch für die entsprechende Klasse.

Im Endeffekt läuft dann in der Businesslogic alles drauf hin, wie Kallisti schon sagte, Factory-Klassen für die Module zu generieren, die die Felder eines Moduls kennen. So spielt die Factory-Klasse eine Rolle bei der Serialisierung und bei der Deserialisierung.

CyberModuleFactory:

  • Java:
    public abstract CyberModuleFactory {
      public abstract CyberModule newObject();
      public abstract CyberModule newObject(Map fieldMap);
      public abstract Map serializeObject(CyberModule cModule);
    }

Dann würde ich noch eine Factory-Klasse für das Cyberschwein selber erstellen (ja es wird sehr klassenlastig, aber es soll ja auch erweiterbar sein), die dann mit maximal 2 Queries das zu erstellende Objekt serialisiert vor sich liegen hat. Die Inhalte aus der Tabelle 3 würde ich in eine Map hauen (ich schreib nun mal weiter die Javasyntax hin :D). Nun brauch die Factory-Klasse vom Cyberschwein nur noch eine Locator-Klasse für die ganzen Factory-Klassen der CyberModule, um diese dann zu nutzen, um die Module zu erstellen und dem deserialisiertem Objekt hinzuzufügen.

Vorteil:

  • Änderung an irgendwelchen Felder eines CyberModules muss nur in der dazugehörigen Factory-Klasse stattfinden, weil wie ein Objekt erstellt wird in den Instanzen darüber nicht ersichtlich ist.
  • Erweitung um zusätzliche Module ist auch kein Problem, weil ich über die Locator-Klasse einfach eine neue Factory-Klasse hinzufüge und somit der ganze Prozess nicht weiter gestört wird. Wenn man ein Modul komplett raushauen will, dann könnte man zb. einfach keinen Link mehr auf die Factory-Klasse geben und schon wird das CyberModule nutzlos
  • skalierbar

Nachteil:

  • Unmengen "sinnloser" Klassen, wenn man nur will, dass es halbwegs funktioniert
  • zu sehr abstrahiert ist beim weiterentwickeln eher kontraproduktiv
gepostet vor 16 Jahre, 2 Monate von Dunedan

ORM! Ich sage einfach nur ORM! *g*

gepostet vor 16 Jahre, 2 Monate von Phoscur

Jup. Genau das!

Ich werd das in PHP auf ein WeltraumBG zuschneiden bzw zugeschnitten schreiben ;D

Die Sache mit den Modulen gefällt mir, nehme ich auf in meinen Plan :D

Ich poste demnächst mal was handfestes, das Konzept hab ich ja schon länger, hab schon ein paar sachen runtergeschrieben.

Sry wenn OT:

Wieviele schreiben hier eig in PHP? Hab bisher nur viel über Java, C* und Ruby gelesen...

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Wobei ich gerade merke, dass man die Tabelle 2 eigentlich nicht brauch.

Es wird ja sicherlich auch eine Tabelle existieren, wo alle möglichen verfügbaren CyberModule enthalten sind. Welche Module das Cyberschwein nun enthält erkennt man ja an der "Tabelle 3", wenn man mal ein DISTINCT-Query über diese Tabelle laufen lässt.

gepostet vor 16 Jahre, 2 Monate von Phoscur

Ja, du kannst ja Parameter für ein Modul in einem Feld verstauen solange du damit nicht innerhalb des MySQL arbeiten willst.

Allerdings könnte es sein, dass wenn man Models - oder Schweine, wie auch immer man sie nennt - verschachteln willst, du eine weitere Tabelle brauchst mit den Ferkeln oder vllt Schiffen der Flotte, die würde ich nur ungern als Module ausgeben. Die Module für Schweine und Ferkel könnte man trotzdem mit einem einzigen Query holen, zumal diese ja nur vom Typ oder der ID des Schweins abhängig sind.

Oder?

PS: Tut mir Leid wenn ich den Topic etwas in meine Richtung ziehe, aber das riecht mir einfach zu sehr nach dem was ich gerade mache, ich hoffe das stört niemanden.

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Original von Phlegma

Ja, du kannst ja Parameter für ein Modul in einem Feld verstauen solange du damit nicht innerhalb des MySQL arbeiten willst.

Die Parameter, oder die eigentlich Felder eines Moduls, auch Klasseneigenschaften, werden ja komplett in der Tabelle 3 gespeichert. Da steht dann zb.:

Code:

ID  |  SchweinId  | ModulId  |  Schlüssel  |  Wert
1          1          2           Leben        100
2          1          2        Lebensbonus     20
3          2          5           Glueck       100

Und wieso sollte ich das in eine Spalte schreiben? Ab Besten noch mit Komma getrennt, damit man nicht danach suchen kann oder im ByteStream, damit man es eigentlich auch gleich lassen kann, weil man da nichts rauslesen kann. (kommt sicher immer drauf an, was man für eine Verwaltung veranschlagt)

Du musst ja auch ein Schritt weiter denken. Ein Script holt Schwein 1 aus der Datenbank und sagt, dass es Weihnachten wird und daher der Bauer ihm viel zu fressen gibt. Also bekommt er zum Beispiel einen Lebensmalus von -10 (aktueller Wert also nun 20-10 = 10). Modul HealthModule hat aber nicht nur 2 Eigenschaften, sondern sagen wir 20.

Wie würdest du nun vorgehen? Würdest du nun dieses Module wieder anfangen zu serialisieren und dann in das eine Feld schreiben? Wenn ich doch nur eine Spalte erneuern müsste - nämlich die Spalte mit der ID 2 (ich beziehe mich immernoch auf die Pseudotabelle da oben). Geschweige denn von der Wartbarkeit des Datenbestandes.

Allerdings könnte es sein, dass wenn man Models - oder Schweine, wie auch immer man sie nennt - verschachteln willst, du eine weitere Tabelle brauchst mit den Ferkeln oder vllt Schiffen der Flotte, die würde ich nur ungern als Module ausgeben. Die Module für Schweine und Ferkel könnte man trotzdem mit einem einzigen Query holen, zumal diese ja nur vom Typ oder der ID des Schweins abhängig sind.

Oder?

Naja das beschriebene Problem vom Fobby ging ja davon aus, dass eine Schweinklasse n Module besitzen soll. Nicht aber das das Module noch m Tierklassen besitzt. Was auch wieder rein vom Gedanke her Mist ist. Oder willst du zum Beispiel eine Superschwein vom Cyberschwein erben? Es geht ihm glaube ich einfach drum, dass er Grundtypen hat, die aber durch bestimmte Module (Ausbauten) erweiterbar und spezifizierbar werden.

Nehmen wir eine Klasse "Soldat". Diese kann auch ausgerüstet werden mit Modulen. Waffen, Anzüge, Granaten, GPS usw. Nun haben meine Forscher aber noch Supersoldaten geschaffen. Die kann ich aber nicht einfach auf den Soldaten draufsetzen, weil Supersoldaten nicht menschlich sind, sondern mechanische Erweiterungen haben. Sozusagen erbt zwar der Supersoldat noch die komplette Ausrüstung, aber er wird ganz anders behandelt. Er bekommt dann halt noch die zusätzliche Ausrüstung "mechanische Organe" oder sowas.

Das Cyberschwein soll sozusagen als finale Klasse fungieren (Zumindest hab ich es so verstanden, wie es beschrieben wurde).

PS: Tut mir Leid wenn ich den Topic etwas in meine Richtung ziehe, aber das riecht mir einfach zu sehr nach dem was ich gerade mache, ich hoffe das stört niemanden.

Wie riechts denn? ;)

gepostet vor 16 Jahre, 2 Monate von Phoscur

Original von KoMtuR

Die Parameter, oder die eigentlich Felder eines Moduls, auch Klasseneigenschaften, werden ja komplett in der Tabelle 3 gespeichert. Da steht dann zb.:

Code:

ID  |  SchweinId  | ModulId  |  Schlüssel  |  Wert
1          1          2           Leben        100
2          1          2        Lebensbonus     20
3          2          5           Glueck       100

Und wieso sollte ich das in eine Spalte schreiben? Ab Besten noch mit Komma getrennt, damit man nicht danach suchen kann oder im ByteStream, damit man es eigentlich auch gleich lassen kann, weil man da nichts rauslesen kann. (kommt sicher immer drauf an, was man für eine Verwaltung veranschlagt)

Naja, wenn du das nicht in eine Zeile sondern in einen SQL-Block schreibst, dann brauchst du eine längere Schleife das zu fetchen und musst sortieren bzw gruppieren oder wir sind wieder bei den Prepared-Statements.

Ich wollte eig die Basiseigenshaften direkt beim Schweineintrag speichern, das wird Tabelle 1 sein bei dir? Die Module sind mir neu, ich hatte noch nicht viel Zeit darüber nachzudenken. Allerdings habe ich Angst, dass wenn ich in einer Flotte (1 Objekt) noch massig Modul-Objekte in den Schiffen (viele Objekte) erzeuge, langsam der Speicher richtung Maximum krebst, PHP ist noch nicht so ueberoptimiert für Objekte, früher war es doch nur prozedural. Andere Sprachen kann ich leider noch nicht, bis ich da etwas zu Stande bekomme dauert es mir zulang und wird dann doch nur zu schrottig.

Du musst ja auch ein Schritt weiter denken. Ein Script holt Schwein 1 aus der Datenbank und sagt, dass es Weihnachten wird und daher der Bauer ihm viel zu fressen gibt. Also bekommt er zum Beispiel einen Lebensmalus von -10 (aktueller Wert also nun 20-10 = 10). Modul HealthModule hat aber nicht nur 2 Eigenschaften, sondern sagen wir 20.

Wie würdest du nun vorgehen? Würdest du nun dieses Module wieder anfangen zu serialisieren und dann in das eine Feld schreiben? Wenn ich doch nur eine Spalte erneuern müsste - nämlich die Spalte mit der ID 2 (ich beziehe mich immernoch auf die Pseudotabelle da oben). Geschweige denn von der Wartbarkeit des Datenbestandes.

Ja, das überzeugt mich. Sollte ich Module verwenden bekommt jede Eigenschaft des Moduls eine eigene Zeile.

Allerdings könnte es sein, dass wenn man Models - oder Schweine, wie auch immer man sie nennt - verschachteln willst, du eine weitere Tabelle brauchst mit den Ferkeln oder vllt Schiffen der Flotte, die würde ich nur ungern als Module ausgeben.

Naja das beschriebene Problem vom Fobby ging ja davon aus, dass eine Schweinklasse n Module besitzen soll. Nicht aber das das Module noch m Tierklassen besitzt. Was auch wieder rein vom Gedanke her Mist ist. Oder willst du zum Beispiel eine Superschwein vom Cyberschwein erben? Es geht ihm glaube ich einfach drum, dass er Grundtypen hat, die aber durch bestimmte Module (Ausbauten) erweiterbar und spezifizierbar werden.

Stimmt, das will er nicht, aber vllt braucht er es doch einmal.

Sieh mal: Sagen wir du hast Flotten mit Schiffen die im Raum rumfliegen. Dann willst du doch nicht jedes Schiff einzeln verschieben. Die Schiffe kommen erst zum Zug wenn etwas spezielles wie zB ein Kampf geschieht, solange ist es nur die Flotte, die benötigt wird. Teils braucht man gar nicht die Schiffe aus der Datenbank holen, wenn man nur Flottenbewegungen ausführt.

Das Cyberschwein soll sozusagen als finale Klasse fungieren (Zumindest hab ich es so verstanden, wie es beschrieben wurde).

Gut, dann wird alles in die Module gestopft. Ich werde eine abtrakte Klasse anlegen die ein paar Sachen vorgibt. Aber Fobby will ja auch etwas anderes schreiben wie ich. Bei mir muss alles extrem variabel werden damit ich es dann überhaupt Engine nennen darf...

Wie riechts denn? ;)

Gut :)

Ich denke, dass ich die Module vllt etwas außen vor lasse, aber im Kopf behalte. Man kann sich ja auch noch etwas für Version Zwei aufheben... Ich muss erstmal sehn wie schnell mein Objektkram in PHP überhaupt ist.

gepostet vor 16 Jahre, 2 Monate von Fobby

So, dann komm ich meiner Pflicht als Threadersteller mal nach und geb meinen Senf dazu :) Erstmal vielen Dank für die vielen Ideen und die schöne Diskussion! Ich habe mir nun alles durch den Kopf gehen lassen und möchte hier meine aktuelle Lösung vorzeigen. Aber zuerst nochmal eine Spezifizierung der gestellten "Aufgabe"

Ich hoffe, das macht es etwas anschaulicher.

Hier nun mein Lösungsvorschlag (weiß nicht mehr genau, welche Beitrag dazu den Anstoß gegeben hat):

Das Attribut CyberSchwein::module wird zu einer Instanz von ModulManager. In dieser bekommt lediglich die schweinid von CyberSchwein, liest dann erst die in das Schwein implementierten ModulIds und dann auf einen Schlag die gesamten Moduldaten - vielleicht sogar in einem Query möglich, sodass es unabhängig von der Modulanzahl 2 Queries pro Schwein sind. Ein weiterer Vorteil, aus CyberSchwein::module ein Objekt zu machen (vorher war es als Liste der Module geplant) ist natürlich, dass ich auch weitergehend sehr komfortabel mit den Modulen arbeiten kann über diverse Methoden wie $schwein->module->add() etc.

Hier noch eine auf das Modell zugeschnittene Datenbankskizze:

schwein_hat_modul

Code:


schweinid modulid
1 1
1 2
2 2
2 3

 module

Code:

id	typ		name		gfx	credits
1 WaffenModul Gausskanone g.gif 100
2 WaffenModul Railgun r.gif 200
3 RuestungsModul Plattenpanzer p.gif 300

 modulspezialisierung

Code:

id	name
1 beschreibung
2 schaden
3 absorption
4 munitionsart

 modul_hat_spezialisierung

Code:

modulid	spezialid	wert
1 2 10
1 4 3
3 3 100
gepostet vor 16 Jahre, 2 Monate von KoMtuR

Original von Phlegma

Naja, wenn du das nicht in eine Zeile sondern in einen SQL-Block schreibst, dann brauchst du eine längere Schleife das zu fetchen und musst sortieren bzw gruppieren oder wir sind wieder bei den Prepared-Statements.

Naja ich gehe nun mal nur von Java aus und wie ich es da anstellen würde. Sicher muss man in php ein wenig anders denken.

Select `ModulId``mid`, `Schluessel``key`, `Wert` `val` FROM `tabelle3`WHERE `SchweinId` = 1 ORDER BY `mid`

Nun hab ich die Daten schon sortiert, so wie ich sie haben will. Dann kommt das fetchen.

Pseudocode:

setze mid = 0
instanziere Map Attribute
instanziere Liste Threads
while(fetch)
wenn(mid != 0 und mid != fetch.mid)
starte neuen Thread mit der Attribute-Map + mid und füge Thread in Liste hinzu
erstelle neue Attribute-Map
mid = fetch.mid
lege ein Eintrag in der Attribute-Map an mit den Werten fetch.key und fetch.value
fetch abgeschlossen und nun noch einen thread starten, wenn die Attribute-Map Daten enthält
iteriere über liste Threads
wenn Thread noch läuft warten
bekomme aus dem ausgelaufenen Thread das erstelle Modul und füge es dem Objekt zu
fertig :P

Ich wollte eig die Basiseigenshaften direkt beim Schweineintrag speichern, das wird Tabelle 1 sein bei dir? Die Module sind mir neu, ich hatte noch nicht viel Zeit darüber nachzudenken. Allerdings habe ich Angst, dass wenn ich in einer Flotte (1 Objekt) noch massig Modul-Objekte in den Schiffen (viele Objekte) erzeuge, langsam der Speicher richtung Maximum krebst, PHP ist noch nicht so ueberoptimiert für Objekte, früher war es doch nur prozedural. Andere Sprachen kann ich leider noch nicht, bis ich da etwas zu Stande bekomme dauert es mir zulang und wird dann doch nur zu schrottig.

Naja nehmen wir mal dein Schiffsproblem und den typischen Spieler. Ein Spieler baut sich ein paar Schiffe zusammen, die spezielle Module haben, und baut diese dann am Stück. Wenn die Module nun nicht schiffsspezifisch sind und nur diesem Typ von Schiff einen Boni gewähren, dann brauchst du nur eine Instanz erstellen. Gegebenfalls man wird doch viele Objekte in einer Flotte haben, dann bauste halt lazy-loading ein, oder in dem Fall eher lazy-deserialize . Ich weiß ja nicht in was für einer Dimension von Flotte du denkst. Darauf kommt es ja auch immer ein wenig an.

Stimmt, das will er nicht, aber vllt braucht er es doch einmal.

Sieh mal: Sagen wir du hast Flotten mit Schiffen die im Raum rumfliegen. Dann willst du doch nicht jedes Schiff einzeln verschieben. Die Schiffe kommen erst zum Zug wenn etwas spezielles wie zB ein Kampf geschieht, solange ist es nur die Flotte, die benötigt wird. Teils braucht man gar nicht die Schiffe aus der Datenbank holen, wenn man nur Flottenbewegungen ausführt.

Mir kommts langsam so vor als würdest du vor Problemen in der eigenen Umsetzung sitzen und nun versuchen einen Weg zu finden, wie man das lösen kann Nur so als Tipp: Schiff gehört zu Flotte und Flotte hat eine Position. Schiff steht auf der Position (dX, dY) (das ist nun delta) vom Ursprung der Flotte.

Das Cyberschwein soll sozusagen als finale Klasse fungieren (Zumindest hab ich es so verstanden, wie es beschrieben wurde).

Gut, dann wird alles in die Module gestopft. Ich werde eine abtrakte Klasse anlegen die ein paar Sachen vorgibt. Aber Fobby will ja auch etwas anderes schreiben wie ich. Bei mir muss alles extrem variabel werden damit ich es dann überhaupt Engine nennen darf...

Machs lieber nicht zu flexibel, sondern robust und skalierbar. Dann kannst du immernoch Ableiten und Implementieren, wie du lustig bist. Die meisten Engines gehen doch kaputt, weil sie die eierlegende Wollmilchsau erreichen wollen.

Wie riechts denn? ;)

Gut :)

Ich denke, dass ich die Module vllt etwas außen vor lasse, aber im Kopf behalte. Man kann sich ja auch noch etwas für Version Zwei aufheben... Ich muss erstmal sehn wie schnell mein Objektkram in PHP überhaupt ist.

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Hier mal meine Vorstellung. Ich hatte nun nur keine Lust mehr das noch so hinzuschieben, dass es so schön wie da oben ausschaut ;)

Dein Modell ist leichtgewichtig, aber hat schon paar Haken. Die ModuleManager-Klasse erzeugt eine Klasse Cyberschwein. Falscher Zuständigkeitsbereich. Dein ModuleManager ist eine Klasse für alle abgeleiteten Modulklassen. also du de-/serialisierst alles in dieser Klasse. Wenn du was erweitern willst oder neue Modultypen hinzufügen willst, dann musst du alles da rein packen. Irgendwann haste ne riesige Klasse.

Die Tabellen kann man eigentlich fast so lassen. Nur eine Anmerkung. Ich weiß du willst das vielleicht nicht so haben. Aber stell dir vor du bekommst dann noch auf die Idee spezielle Modultypen einzubauen. Diese Modultypen sind schweinchenspezifisch. Nenn wir es mal UniqueModule. Eine konkrete Implementierung wäre zum Beispiel ein Fluxkompensator oder ein Seelensammler (ich weiß ja nicht ob dein Schweinchen im Weltraum fliegt oder durch ne Psychowelt dackelt  ). Nehmen wir den Seelensammler. Der Sammler läd sich pro getötetes Feindschweinchen auf. Wenn ein bestimmter Wert erreicht ist dann gibts ne Überraschung. Sowas zum Beispiel. Oder wenn dein Schweinchen nun anfängt Hunger zu bekommen (Treibstoff). Dann müssten die Module immer unterschiedliche Werte beinhalten. also für jedes Schweinchen. Das würde mit deinem Datenbankkonzept nicht funktionieren. Nur so ein Anstoß wegen Erweiterbarkeit.

Kurz zu meinem Diagramm und ne kurze Erklärung. CyberPig ist klar. CyberPigFactory ist deine Einstiegsklasse (Man könnte noch ein CyberPigService drüber bauen, der dann save und load als Funktionen hat und somit diese Sachen von der Factory löst). Die Funktion newPig stellt nun die Anfrage an die Datenbank und holt alle Daten (ausser die Modulebeschreibungen, die liegen alle im CyberModuleService). Erst wird ein neues CyberPig erstellt und danach wird der CyberModuleService aufgerufen, um die Module zu serialisieren. Er gibt dann deine Werte aus der Tabelle mit (in meiner vorherigen Darstellung dieses key/value Zeugs) und die ID des Moduls.

Der Service hat ein Array von den ganzen ModuleFactory-Implementierungen und entscheidet anhand der ID, welche er dann auswählt und ruft newModule mit den spezifischen Daten aus der DB auf (ich würde da wirklich auf ein assoziatives Array setzen und dies dann als Parameter der Factory übergeben, weils den Service nicht interessiert, wie das Modul erstellt wird).

Die Implementierungen von ModuleFactory erstellen nun ihr zugeteiltes Modul und geben das zurück. Der Service gibt es dann der CyberPigFactory zurück und diese hängt die dann an die instanzierte CyberPig-Klasse.

Das Speichern in die Datenbank geht genauso, nur dass da eben die CyberPigFactory durch ein Service ergänzt werden sollte (sehe gerade das ich in der Factory eine Methode zum serialisieren in die DB vergessen hab...). Wirst es sicherlich mit php machen. Da würde ich paar Abstraktionsstufen auslassen ;)

edit: Diagramm aktualisiert

gepostet vor 16 Jahre, 2 Monate von Amun Ra

Das hört sich für mich schon nach ziemlichem overkill an.
Die armen Spatzen die immer mit der OOP Kanone beschossen werden ;) ...
Ich hoffe für den Threadersteller, das die Sprache seiner Wahl nicht PHP ist.
Sonst könnten die 500 Objekte und Queries den Server schon gut in die Knie zwingen.

gepostet vor 16 Jahre, 2 Monate von KoMtuR

ja für sein Problem (am Anfang klang es bißchen anders), ist es sicherlich auch nicht nötig. Ich dachte erst, dass jedes Modul für ein Schiff separat agieren soll ;)

gepostet vor 16 Jahre, 2 Monate von Fobby

Wieso denn auf einmal Schiffe, es sind doch süße kleine Meerschweinchen ;)

Dein Modell ist leichtgewichtig, aber hat schon paar Haken. Die ModuleManager-Klasse erzeugt eine Klasse Cyberschwein. Falscher Zuständigkeitsbereich.

Dann habe ich das falsch dargestellt - CyberSchwein beinhaltet einen ModulManager (und zwar in CyberSchwein::module) und nicht andersherum. Bin erst seit kurzem dabei, mich in die OOP-Thematik einzuarbeiten und bin mir über die Symboliken noch nicht 100%ig im Klaren.

Das hört sich für mich schon nach ziemlichem overkill an.
Die armen Spatzen die immer mit der OOP Kanone beschossen werden ;) ...
Ich hoffe für den Threadersteller, das die Sprache seiner Wahl nicht PHP ist.
Sonst könnten die 500 Objekte und Queries den Server schon gut in die Knie zwingen.

In der Tat, es soll in PHP umgesetzt werden. Jedoch werde ich gewiss nicht den von KoMtuR vorgeschlagenen Präzisionslasersatelliten ins All schießen um damit einen Spatz abzuschießen. Es wird auch nie 500 Schweine geben, eher 5-10.

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Original von Fobby

Wieso denn auf einmal Schiffe, es sind doch süße kleine Meerschweinchen ;)

Phlegma hat mich mit seinen Schiffen angesteckt ! ;)

Dein Modell ist leichtgewichtig, aber hat schon paar Haken. Die ModuleManager-Klasse erzeugt eine Klasse Cyberschwein. Falscher Zuständigkeitsbereich.

Dann habe ich das falsch dargestellt - CyberSchwein beinhaltet einen ModulManager (und zwar in CyberSchwein::module) und nicht andersherum. Bin erst seit kurzem dabei, mich in die OOP-Thematik einzuarbeiten und bin mir über die Symboliken noch nicht 100%ig im Klaren.

Naja aber dein ModuleManager ist abhängig vom Schwein. Er beinhaltet ja auch die Id von dem. Also wird der ModuleManager nur Module erzeugen können, die mit dem Typen CyberSchwein zu tun haben. Was ist wenn die Cyberhühner kommen? dann musste wieder ein neuen Manager dafür implementieren, anstatt dem Manager einfach nur die Daten zu geben, die er brauch. Darauf wollte ich hinaus. Theoretisch könntest du dann gleich den Manager weglassen und alles im Schwein machen, weil der Manager derzeit, laut deiner Skizze, eh nur eine Aufgabe hat: Hol dir die Module für den Typen Schwein. Und die Zeichen sind ja nicht so wild. Ich hatte das schon irgendwie verstanden

Das hört sich für mich schon nach ziemlichem overkill an.
Die armen Spatzen die immer mit der OOP Kanone beschossen werden ;) ...
Ich hoffe für den Threadersteller, das die Sprache seiner Wahl nicht PHP ist.
Sonst könnten die 500 Objekte und Queries den Server schon gut in die Knie zwingen.

In der Tat, es soll in PHP umgesetzt werden. Jedoch werde ich gewiss nicht den von KoMtuR vorgeschlagenen Präzisionslasersatelliten ins All schießen um damit einen Spatz abzuschießen. Es wird auch nie 500 Schweine geben, eher 5-10.

Ja naja ich wollte es halt generell machen. Skalierbar halt. Sicherlich ist so eine Struktur in php eher Blödsinn. Nur solltest du den Manager vielleicht doch etwas unabhängiger machen. Oder nenn ihn SchweinModuleManager   Und solange deine Module so einfach bleiben bringt auch ein lazy loading nichts, ausser man baut das dann direkt in die Schweinklasse ein und geht dann immer über getModule() oder so. Also das war gerade auf die Objektanzahl bezogen ;)

gepostet vor 16 Jahre, 2 Monate von Phoscur

Ich denke das wird schon in PHP gehn, zumal bei mir pro Schweintyp immer nur ein Objekt pro Herde rumfahren wird, allerdings gibt es wohl einige versch. Schweintypen. Ich denke das wird PHP schon mitmachen.

Was ich nicht verstehe:

Du benutzt Manager und Services um die Schweine und deren Module zu erstellen? Ich sehe da nur die Aufgabe das Schwein zu holen und nachher wieder in der DB zu aktualisieren. Was ist nun der Unterschied zwischen Factory, Manager und Service?

Sorry, dass ich noch einige Probleme mit den ganzen Begriffen habe. Ich hatte mir da meine eigenen zurecht gelegt^^... Bin gerade dabei etwas über Entwurfsmuster zu lesen und trotzdem im Stress mit der Schule und Familie. Zum Glück eilt es nicht so sehr. Es soll doch lieber gut als schnell hingepfuscht werden ;D

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Factory = Fabrikmethode:

Da Fabriken immer was erstellen sind Factorys zum Erstellen von Objekten zurständig. Diese Klasse (meist sind da nur statische Funktionen drin oder die allgemeine Factory ist abstrakt (AbstractFactory-Pattern). Also ich benutze derzeit vereinzelt das AbstractFactory-Pattern bei Sachen, wie zum Beispiel um Daten auf unterschiedliche Datenbanken zu speichern. Die abstrakte Klasse dient dabei nur als Vermittler und holt sich aus einer Konfiguration die eigentliche Klasse und nutzt diese intern (Singleton normalerweise).

Service und Manager könnte man sicherlich zusammenfassen:

Das sind die Schnittstellen für das Programm, wo man das Objekt selber editieren will (oder es eben benutzen).

Hast du eine Klasse User, dann ist der Service dafür da den User aus deiner Persistenzlogik (also db oder ähnliches) zu laden, ihn dort zu speichern, User zu duplizieren und was noch so anfällt. User loggt zb. aus und dann wird eine funktion logout beim Service aufgerufen und der macht dann alles, was man damit machen muss (auf offline setzen und alles löschen und so). Wobei der Service sicherlich wieder auf die Fabrikklassen zugreift, weil diese einfach nur weiter unten in Applikationsschicht liegen.

Also eigentlich brauch man diese Schichten nicht. Aber es geht darum, dass wenn man an dem Objektaufbau was ändert nur die Fabrikklasse anzuschauen und das dann dort zu ändern und nicht an 100 Stellen im Code. um mal einen zu zitieren auf die Frage, wozu das dient:

ich würde weitergehen und sagen den Vorteil versteht man erst, wenn man es zunächst "ohne" gemacht hat und nachfolgend ändern muß *g*

Beim Service ists genau das gleiche. Du schaffst zentrale Punkte in deinem System, worauf alle zugreifen. Somit verringert sich der Aufwand, wenn du was ändern musst. Theoretisch könntest du über die Services nochn Locator basteln, der dir dann den nötigen Service zurückliefert. Sozusagen sind Locator-Klassen die abstrahierte Schnittstelle von deiner Applikationslogik (im MVC-Modell die Controller- und Modellebene). Ausserdem wenn man an einen Punkt kommt, wo man das System verteilen muss, dann muss man nur verschiedene Ebenen austauschen (In Java nur den Locator, weil der die Daten ja nun von einem anderen Rechner brauch) und die Präsentationsschicht bleibt gleich.

Paar Standardbibliotheken von Java gehen soweit, dass sie den Konstruktor eines Objektes private machen und dann statische Methoden dafür bereitstellen. Ist sozusagen auch ne Art Factory - nur im Objekt selber.

auf die Realität bezogen: Chef(Locator) gibt Aufträge an Abteilungsleiter (Service) und holt sich neue Arbeitskräfte (Factory), die dann die Arbeit "produzieren". Im Endeffekt weiß der Chef nicht was seine Abteilungen machen und die Abteilungsleiter nicht, was die Arbeitnehmer überhaupt veranstalten

gepostet vor 16 Jahre, 2 Monate von Phoscur

Ich weiß nicht, diese Factories... irgendwie hab ich nicht das Gefühl, dass ich für das Erstellen der Schweine eine Fabrik brauche. Wenn alle Schweine voneinander abstammen, dann muss man halt spezielles anders nachreichen, aber eigentlich werden sie doch alle gleich geboren... selbst das UltraBattleSchwein *gg

Ich brauche also einen Service der mir die Daten aus der DB holt und in die Objekte packt. Der Service sorgt auch für einen Cache, indem er die Schweine am Ende des Scripts serialisiert und in der Session speichert. Speicherst du auch nochmal serialisiert in der DB?? Ich seh bei deinem Schema so viel serializePig uÄ.

Da das holen aus der Datenbank teils schweinspezifisch besondere Queries haben kann wollte ich Requester verwenden, die können die Daten auch gleich zwischenspeichern und das Update am Ende erleichtern.

ich weiß, dass ich mich etwas vom AbstractFactory Pattern entferne, aber ich denke das ist nicht so schlimm.

Was früher bzw auf meinem Blog DataHandler heißt bekommt somit den Namen Service, Model werde ich in etwas meiner Wahl umwandeln, so ähnlich wie CyberSchwein ;D, da das wohl nicht der richtige Begriff war.

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Das scheint am Anfang immer sinnlos, bis man an eine Stelle kommt, wo man merkt, dass man haufen ändern muss ;)

Hatte mal bei einer Seite, wo es auch um Creational Patterns ging, also Patterns, die zur Objekterzeugung geeignet sind, gelesen, dass es Ziel ist kein new-Operator in einem Script zu haben Aber ich denke das ist dann immer Sache der Projektgröße. Aber du darfst nicht nur an das hier und jetzt denken. Wenn du zum Beispiel ein Konstruktor änderst, dann musste auf die Änderung nur in der Factory drauf eingehen und da dann vielleicht nen Default-Wert setzen.

Deswegen auch das Zitat. Grundsätzlich kannst du sagen die Schweine stammen eigentlich alle voneinander ab. Nur leider sind sie doch unterschiedlich, weil sie andere Module an sich haben. Die CyberPigFactory dient bei deinen Scripten, die von aussen zugreifen einfach nur als Schnittstelle, um das, was dahinter passiert zu verstecken. Diese newPig()-Funktion kann ja auch überladen mit anderen Parametern existieren. Also einmal nur stinknormal als CyberPigFactory::newPig() oder auch als CyberPigFactory::newPig(id).
Bei der ersten Variante scheint es recht simpel, was dahinter passiert. es wird new CyberPig() aufgerufen. Aber es könnte ja auch new CyberPig(0, "Hausschwein") aufgerufen werden, wenn dein System innerhalb ein Cyberschwein mit den Namen "Hausschwein" als undefiniert betrachtet. Also ohne weitere Spezialisierung und ohne Module.
Die zweite Variante versteckt dem ausführenden Programm lediglich, wie er denn, und vorallem wo er die Daten hernimmt und zusammenbaut. Wo die Factory die Daten herbekommt weiß sie vielleicht selber nicht, sondern schickt einfach nur ein Query an eine Klasse, die halt auf einer Persistenzschicht hängt - also deine DB zb.

Theoretisch wäre es dumm in meinem Model, dass die Factory am Anfang alle Daten bekommt. Also auch die von den Modulen, obwohl sie es nicht brauch. Theoretisch könnte es dann, mit ein wenig umbau, eine Anfrage an die ModuleFactory erstellen, doch mal bitte ein Modul mit der id x zu erstellen. Wie die das dann macht ist ja auch erstmal wieder egal. Aber da ein Modul nie alleine existieren kann, weil es immer an irgendein Objekt gebunden ist, habe ich dann halt Methoden benannt, die ein assoziatives Array (Map) bekommen und sich ihre benötigten Werte rauspicken. Denn ihre Felder kennen sie ja - die Factories.

So hatte ich mir den Ablauf vorgestellt. die serializeXXX und deserializeXXX Funktionen dienen in erster Linie dazu, dass aus dem assoziativen Array ein Objekt wird. Zumindest in dem Beispiel. Wie die Deserialisierung/Serialisierung auszusehen hat liegt in der Obhut der ModuleFactories. Da leitet der Service nur die Daten weiter. wobei der Service schon im groben wissen sollte, was ihn da erwartet. Aber wenn, dann macht der nur ein oberflächigen Check und muss nicht verstehen, wie du Zusammenhänge sind. Das Cachen ist zwar derzeit nicht mit drin, aber das Modell lässt sich ja erweitern. Man könnte den CyberModuleService noch mit einer Cache-Funktion dekorieren (Decorator Pattern). Das gezeigte Modell hat aber derzeit nur einen Sinn:

Wie bekomme ich die unstruktierten Daten aus der Datenbank und wieder zurück.

Was soll denn dein Requester machen? Also die Informationen sind ein wenig dürftig ;) Also soll der vorgefertige Query-Templates haben oder wie meinste das? Man könnte zum Beispiel so ne Art Proxy um die geladenen Klassen machen und die checken immer, ob sich das Objekt geändert hat (nur in php sicherlich nicht gerade so einfach zu erledigen) und dann am Ende des Scriptablaufes wird dann jedes Objekt, wo der Proxy meint, dass es sich geändert hat, zurück in die DB geschrieben. Nur müssteste dann die Objekte den ganzen Scriptablauf irgendwo zwischenspeichern, damit du am Ende noch weißt, welche denn überprüft werden müssen ;)

Ob du dein DataHandler nun Service nennst ist eigentlich geal. Kommt ja drauf an was er macht ;) Und du sollst ja nicht immer einem Pattern folgen, was auch Mist ist, sondern du sollst für das Problem das passende Pattern finden und dies umsetzen. Ich glaube da gibts auch ein Antipattern dafür, der das falsche verwenden der Design Patterns beschreibt

gepostet vor 16 Jahre, 2 Monate von Phoscur

Gut. Ich brauche die Factories nur, wenn ich versch. Kontruktoren habe. Dann macht die Factory den switch und läd evtl weitere Daten; danke dann hab ich das auch verstanden.

Ich hatte aber vorgesehn alle Schweine insofern ähnlich zu machen, dass sie den gleichen Konstruktor haben. Ich wollte diesen sogar final deklarieren. Aber wenn du sagst, dass es zu Änderungen kommen könnte und ich aus diesem vorliegenden Entwurfmuster ersehe, dass es so bereits funktioniert, dann werde ich nicht das Risiko eingehen etwas anderes zu probieren, die Probleme sind vllt noch nicht ersichtlich.

Zurück zum Requester: Er versteckt wahrscheinlich später komplett die Datenbank und erfüllt dabei zwei Aufgaben.

1. Das SELECT, wie du bereits gedacht hast besitzt er dafür schweinspezifisch Schablonen. Natürlich gibt es auch eine Basisklasse, in der der Großteil bereits angelegt ist und welche bereits die Schnittstelle zum Service oder der Factory darstellt.

2. Das UPDATE: Während des SELECTs hat er die gefetchten Datenarrays kopiert und speichert ein Backup. Am Ende des Scripts bekommt er die veränderten Arrays zurück und vergleicht diese mit den Backups (array_diff[_*]). Aus den veränderten Daten formuliert er das (Massen-)Update-Query.

[3. Ein INSERT bei der Neuerschaffung von Daten..?

4. Cleanup/Löschfunktion(en)? frei erweiterbar...]

gepostet vor 16 Jahre, 2 Monate von KoMtuR

Original von Phlegma

Gut. Ich brauche die Factories nur, wenn ich versch. Kontruktoren habe. Dann macht die Factory den switch und läd evtl weitere Daten; danke dann hab ich das auch verstanden.

Brauchen tust du garnichts. Patterns sind keine Plficht sondern Programmierempfehlungen. Und wenn dann solltest du Factories überall nehmen. Egal ob ein Konstruktor oder mehrere. Du weißt nicht wie sich die Zukunft entwickelt.

Ich hatte aber vorgesehn alle Schweine insofern ähnlich zu machen, dass sie den gleichen Konstruktor haben. Ich wollte diesen sogar final deklarieren. Aber wenn du sagst, dass es zu Änderungen kommen könnte und ich aus diesem vorliegenden Entwurfmuster ersehe, dass es so bereits funktioniert, dann werde ich nicht das Risiko eingehen etwas anderes zu probieren, die Probleme sind vllt noch nicht ersichtlich.

Ja ähnlich vielleicht. Du darfst halt nicht nur an das hier und jetzt denken. Ich will da auch nichts vorschreiben. Wie jemand etwas umsetzt ist ja auch sein Ding. ;) Ich würde die wenigstens Funktionen finalisieren, ausser das ich wirklich nicht will, dass die jemand überschreibt. Aber wie gesagt. Das ist Ermessenssache und vielleicht hatte ich noch nicht solche Fälle.

Zurück zum Requester: Er versteckt wahrscheinlich später komplett die Datenbank und erfüllt dabei zwei Aufgaben.

1. Das SELECT, wie du bereits gedacht hast besitzt er dafür schweinspezifisch Schablonen. Natürlich gibt es auch eine Basisklasse, in der der Großteil bereits angelegt ist und welche bereits die Schnittstelle zum Service oder der Factory darstellt.

2. Das UPDATE: Während des SELECTs hat er die gefetchten Datenarrays kopiert und speichert ein Backup. Am Ende des Scripts bekommt er die veränderten Arrays zurück und vergleicht diese mit den Backups (array_diff[_*]). Aus den veränderten Daten formuliert er das (Massen-)Update-Query.

[3. Ein INSERT bei der Neuerschaffung von Daten..?

4. Cleanup/Löschfunktion(en)? frei erweiterbar...]

Am Besten nochmal überprüfen, ob die Daten, die der Requester dann zum speichern bekommt, auch valide sind ;) Also vielleicht macht er es schon und ich habs nur übersehen *g*

gepostet vor 16 Jahre, 2 Monate von Phoscur

Am Besten nochmal überprüfen, ob die Daten, die der Requester dann zum speichern bekommt, auch valide sind ;) Also vielleicht macht er es schon und ich habs nur übersehen *g*

Was würdest du denn validieren? Array? Felderkorrektheit (das hab ich noch nicht drin..)?

Hab ich da richtig rausgehört, dass das Schema ansonsten in Ordnung ist? ;D

gepostet vor 16 Jahre, 2 Monate von KoMtuR

naja kommt ja drauf an wie du die daten wieder an die DB übergibst. Prepared Statements? oder normale. Sonst könnte man in einer extra php datei halt die tabellenstruktur speichern. Dann weiß man ob man s, i,d oder b nehmen muss. Auch hast du dein Query-Template schon in Form eines prepared statements.

Naja ob ich es in Ordnung finde oder nicht ist ja auch egal oder? ;) Solange es gut funktioniert und keine unnötigen Ressourcen frisst kannste ja gut damit fahren. kommt mir zwar wie eine God-class vor, aber vielleicht sehe ich auch nur nicht die Details, weil du ja nurn Überblick gezeigt hast

gepostet vor 16 Jahre, 2 Monate von Phoscur

Ne, ich hab irgendwo gelesen dass ein Multi-Query schneller ist, mit CASE dann.

Hmm, ich muss einfach mal sehn wie das wird, wird ja erstmal nur ne 0.1, weitere Versionen sind vorgesehn.

Auf diese Diskussion antworten