lilith2k3 Geschrieben 25. April 2011 Geschrieben 25. April 2011 (bearbeitet) Hallo liebe Forengemeinde, ich würde mich gerne im Bereich der OO Programmierung weiterentwickeln. Ich habe auch schon im Internet gesucht und leider wenig konkretes gefunden - abgesehen von Hinweisen auf Fachliteratur, die ich leider nicht so ohne weiteres einschätzen kann. Mein bisheriges Vorgehen schildere ich einmal beispielhaft an einer fiktiven Schnittstelle zwischen zwei Datenbanken: Die direkte Connection zu den zwei Datenbanken wird in zwei gesonderte Klassen verpackt. Diese beiden Objekte werden per Dependency Injection in die jeweiligen Adapterklassen eingefügt. Objekterzeugung übernehmen Factoryklassen (bzw. das DI-Framework). Soweit der "grundlegende Aufbau". Meine Frage bezieht sich auf die Objektkommunikation: Bisher gehe ich hin und habe quasi eine main()-Funktion, die den Einstiegspunkt in die Anwendung darstellt und über die auch die Objekterzeugung und komplette Kommunikation der Objekte abgewickelt wird: Pseudocode: public static void main(){ DatabaseConnectionA connA = DatabaseConnectionFactory.GetConnection("A"); DatabaseConnectionA connB = DatabaseConnectionFactory.GetConnection("B"); DataTransformator transformator = TransformatorFactory.GetTransformator(); DatabaseAdapterA adapterA = DatabaseAdapterFactory.GetAdapter(connA); DatabaseAdapterB adapterB = DatabaseAdapterFactory.GetAdapter(connB); EmployeeCollection employeeCollection = adapterA.RetrieveAllEmployees(); TransformedCollection transformedEmployeeCollection = transformator.PutDataInShapeForAdapterB(employeeCollection); adapterB.StoreAllEmployees(transformedEmployeeCollection); } [/PHP] Ist ein solches Vorgehen okay? Oder ist das zu "prozedural" gedacht, da der eigentliche Kontrollfluss nicht den einzelnen Objekten überlassen wird, sondern in [i]main()[/i], bzw. dem "Hauptobjekt" stattfindet? Alternativ könnte ich mir folgedes vorstellen: Es könnte die Transformator-Klasse eine Referenz zu beiden Objekten erhalten, so dass der Informationsfluss statt durch die [i]main()[/i] eben durch die Transformator-Klasse liefe. In der main() bliebe dann lediglich die Erzeugung der jeweiligen Objekte über und das Anstossen des Übertragungsvorgangs. Aber lagere ich damit "mein Problem" nicht in diese Transformator-Klasse aus? :confused: Zumindest hat der "prozedurale" Code den Vorteil, dass offensichtlich ist, was ich wie mache.:beagolisc Vielen Dank für Tips :] Bearbeitet 25. April 2011 von lilith2k3 Zitieren
Genodi Geschrieben 25. April 2011 Geschrieben 25. April 2011 Hi, also ich kann nur sagen, wie ich es in Java gelernt habe. Du kennst da ja sicher die DAO's (Data Access Object). Jede Klasse hat ein eigenes DAO. Dieses regelt den gesamten Zugriff auf die DB. Was nämlich auch sehr wichtig war, alich ich das geschrieben habe ist, dass die Transaktionen auch entweder dynmaisch oder über die entsprechende Factory-Klasse laugen. Du hast dann quasi ein EmpleoyerDAO und kannst "beispielsweise" sagen: EmploeyerDAO.getById(blablub) und du kriegest den Employer zurück. Kann aber sein, dass du das schon kennst. So hättest du eine recht komplexe Klasse, die alles steuert, aber dafür hast du in deinem eigentlichen Programmcode nicht mehr so viel mit Datenbankanbindung zu tun. Wenn es weiterhilft, ich hab hier einige Beispiele und Konzepte wie ich das in der Arbeit realisiert habe. Aber wie gesagt, ich habe das in Java gemacht und wollte das mal demnächst auch in Delphi mal probieren. Da gibt es nur einen Unterschied: Ich habe Hibernate in Java benutzt und in Java hat man Annotations. Ich kenne das Problem. Ich hoffe, ich habe dich richtig verstanden, wenn ja, dann kann ich mehr erzählen, wenn nicht, dann sorry. Mich interessiert das Ergebnis hier auch auf jeden Fall. Gruß! Zitieren
lilith2k3 Geschrieben 25. April 2011 Autor Geschrieben 25. April 2011 Du kennst da ja sicher die DAO's (Data Access Object). Jede Klasse hat ein eigenes DAO. Dieses regelt den gesamten Zugriff auf die DB. Darum geht es eigentlich weniger. Die eigentlichen Adapterklassen habe ich von den darunterliegenden Datenbankanbindungen entkoppelt. Das habe ich quasi mit den DatabaseConnection-Klassen andeuten wollen. Die sind für die "schmutzigen" Details zuständig (da wäre dann auch die Anbindung für ORM mittels Framework zu verorten). Bei der EmployeeCollection handelt es sich dann um soetwas wie ein DAO, resp. eine Collection von DAOs. Du hast dann quasi ein EmpleoyerDAO und kannst "beispielsweise" sagen: EmploeyerDAO.getById(blablub) und du kriegest den Employer zurück. Kann aber sein, dass du das schon kennst. Jo. Im Grunde sollte das so in dem Beispiel angedacht sein. So hättest du eine recht komplexe Klasse, die alles steuert, aber dafür hast du in deinem eigentlichen Programmcode nicht mehr so viel mit Datenbankanbindung zu tun. Das ist unter anderem noch ein Nebeneffekt: Nicht nur, dass mir das Design von main() recht prozedural erscheint - und ich noch nicht weiss, ob sowas "schlimm" ist- sondern die Hauptklasse würde zu einer Art Megaobjekt; alle Kommunikationskanäle liefen ja auch da zusammen. Nicht nur, dass hier das wiring up, also das Zusammenbauen der einzelnen Objekte erfolgt, sondern eben auch die Programmlogik stattfindet. Und nach einigem Arbeiten mit und Nachdenken über OOP kommt mir das nicht richtig vor, zumindest bin ich mir nicht (mehr) sicher und hätte gerne eine Stellungnahme von den etwas erfahreneren Programmierern gehabt. Zitieren
NerdonRails Geschrieben 28. April 2011 Geschrieben 28. April 2011 Pseudocode: public static void main(){ DatabaseConnectionA connA = DatabaseConnectionFactory.GetConnection("A"); DatabaseConnectionA connB = DatabaseConnectionFactory.GetConnection("B"); DataTransformator transformator = TransformatorFactory.GetTransformator(); DatabaseAdapterA adapterA = DatabaseAdapterFactory.GetAdapter(connA); DatabaseAdapterB adapterB = DatabaseAdapterFactory.GetAdapter(connB); EmployeeCollection employeeCollection = adapterA.RetrieveAllEmployees(); TransformedCollection transformedEmployeeCollection = transformator.PutDataInShapeForAdapterB(employeeCollection); adapterB.StoreAllEmployees(transformedEmployeeCollection); } [/PHP] Ok, meine Idee wäre eine Continuation. Folgende API würde mir da einfallen und auch gefallen: [PHP] DatabaseConnectionA connB = DatabaseConnectionFactory.GetConnection("B"); DatabaseAdapterB adapterB = DatabaseAdapterFactory.GetAdapter(connB); var myDataOperation = adapterB.StoreAllOfType<Employee>().WithDataFrom<DatabaseAdapterA>().Using<DataTransformator>(); myDataOperation.Execute(); adapterB würde dir hier z.B. ein StoreAllContinuation-Objekt zurückgeben das WithDataFrom() zur Verfügung stellt welches eine DataCollectContinuation zurückgibt die dann mit einem instanzierten DataTransformator die Daten aufbereitet und der ersten Continuation zur Verfügung stellt. Be der Komposition der Klassen ist dann etwas Phantasy und Arbeit gefragt. Die Lösung dürfte dann aber sauberer, wiederverwendbarer und besser lesbarer sein. Zitieren
lilith2k3 Geschrieben 28. April 2011 Autor Geschrieben 28. April 2011 Heyo Schön, dass sich nochmal jemand dazu meldet - ich hatte die Hoffnung schon fast aufgegeben. Aber ist ja auch nicht gerade beginner's level. Ich selber habe nocheinmal darüber meditiert und im Nachhinein gefällt mir mein Design auch nicht mehr. Und ich habe es im Kopf auch schon überarbeitet. An dieser Stelle vielen Dank an Dich NerdonRails, Du hast mich mit dem Fluent Interface auf eine coole Idee gebracht - die obendrein gut lesbar ist! Vielen Dank! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.