Abstract Factory
Nick
- programmiertechnik
Hallo,
ich hab ne Abstract Factory nachprogrammiert, mit folgenden Klassen (das gif am besten abspeichern und dann vergrößern):
http://marcogomez.beepworld.de/photoalbum/100919/881963_l.gif
1. Frage
Muss/Soll man die Methode creatUser auch im Client/Schnittstelle implementieren?
Ich möchte ja später mit der Schnittstelle arbeiten, wenn die Schnittstelle aber kein createUser enthält, wäre das nicht so praktisch.
2. Frage
Die konkrete Fabrik erstellt mir ja einen User mittels der Methode createUser()
Nun ist es aber so, dass (die Anwendung läuft auf einem Server und auf mehreren Clients) auch ein Client einen User erstellen kann. Der Client hat jedoch keine Datenbank, und deswegen wäre es ja auch sinnlos eine DatabaseFactory zu erstellen. Darf man den User also auch direkt über das BusinessObject::User erzeugen, oder darf man dafür nur die createUser() der konkreten Fabrik verwenden?
Ich hoffe ich hab das irgendwie verständlich formuliert. Bitte keine Links posten, ich hab ein paar Tutorials durchgearbeitet. Aber diese Punkte oben, verstehe ich eben noch nicht ganz. Wäre nett wenn man dir Fragen direkt beatworten könnte. Vielen Dank schon mal im Voraus!
LG
Hallo Nick,
Der Sinn einer abstrakten Fabrik ist es ja, vor dem Aufrufer zu verbergen, was er genau instanziert und wie das abläuft. Wenn man so etwas verwendet, sollten eigentlich auch alle Instanzierungen über die Factory laufen, sonst verliert man ja die Austauschbarkeit der Implementierung und kann sich die Factory damit auch schenken.
Es kann Ausnahmen geben, wenn man in einem ganz speziellen Fall mal eine konkrete Implementierung verwenden muss, das scheint mir aber nicht gegeben zu sein.
Dein DatabaseClient/IDatabaseClient ist was? Für mich sieht es nach einer Art Fassade aus, über die die GUI-Schicht o.ä. auf die "Business"-Schicht zugreift.
- Frage
Muss/Soll man die Methode creatUser auch im Client/Schnittstelle implementieren?
Ich möchte ja später mit der Schnittstelle arbeiten, wenn die Schnittstelle aber kein createUser enthält, wäre das nicht so praktisch.
Mir ist noch nicht ganz klar, was die Schnittstelle tut. Ich vermute aber, dass die Antwort "Ja" ist. Die Frage ist dann eher, wie man sie implementieren sollte.
- Frage
Die konkrete Fabrik erstellt mir ja einen User mittels der Methode createUser()
Nun ist es aber so, dass (die Anwendung läuft auf einem Server und auf mehreren Clients) auch ein Client einen User erstellen kann. Der Client hat jedoch keine Datenbank, und deswegen wäre es ja auch sinnlos eine DatabaseFactory zu erstellen. Darf man den User also auch direkt über das BusinessObject::User erzeugen, oder darf man dafür nur die createUser() der konkreten Fabrik verwenden?
Wie gesagt sollte das normalerweise über die Fabrik laufen.
Wenn ich das richtig verstehe, gibt es bei Dir eine Client-Anwendung und eine Server-Anwendung die über irgendetwas kommunizieren?
Die Business-Objekte kommen dann auf dem Client und dem Server vor und werden irgendwie ausgetauscht/synchronisiert.
Wo liegt nun Deine Datenbanklogik? In den Business-Objekten? Wenn ja, dann brauchst Du vermutlich sowieso für Client und Server unterschiedliche Implementierungen der Objekte und der Factory (womit das Muster dann wenigstens einen gewissen Sinn ergäbe ;-)
Liegt die Logik irgendwo anders, brauchst Du evtl. den ganzen Factory-Kram nicht (wenn es keinen Grund für unterschiedliche Implementierungen gibt) und dann darfst Dir was anderes überlegen ;-)
In einer "modernen", "einfachen" Client-Server Anwendung mit Datenbank würde man wohl sowas machen:
Es gibt Business-Objekte, die datenbankunabhängig sind und auf Client und Server verwendet werden. Die werden auf Client und Server gleichermaßen verwendet und dazwischen ausgetauscht oder synchronisiert.
Wenn der Client einen Benutzer anlegt, instanziert er ein Benutzer-Objekt, befüllt es mit Daten und ruft beim Server "createUser(Benutzer-Objekt)" auf.
Das speichern in die/laden aus der Datenbank übernimmt dann ein System wie Hibernate, das das mehr oder weniger Transparent erledigen kann.
Sowas bringt allerdings nochmal eine ganze Menge Einarbeitungsaufwand mit sich, den Du Dir vermutlich zum jetzigen Zeitpunkt noch nicht antun solltest.
Generell scheint mir Dein Entwurf noch etwas chaotisch. Weißt Du wirklich, warum Du welches Muster verwendest?
Grüße
Daniel
Hallo Daniel,
vielen Dank für deine sehr ausführliche Antwort! Also, ich habe hier folgende Vorlage verwendet: http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
Ich implementiere einen Server, auf diesem können sich Benutzer registrieren, im Hintergrund läuft auf dem Server eine PostgreSQL Datenbank. Es handelt sich überall um Java/Windows-Applikationen. Also KEINE Webanwendung.
Der Benutzer startet die exe auf dem Client. Anschließend kann er sich entweder einloggen oder registrieren. Die Kommunikation zwischen Server und Client läuft über RMI.
Die Datenbanklogik liegt (wie in der Vorlage von java.sun.com) in der DatabaseFactory z. B. createConnection und in DatabaseClient z. B.
deleteUser (delete from ... where userid=...).
Dein DatabaseClient/IDatabaseClient ist was? Für mich sieht es nach einer »» Art Fassade aus, über die die GUI-Schicht o.ä. auf die "Business"-Schicht »» zugreift.
Es kann ja sein, dass es verschiedene Konkrete Fabriken gibt. So weit ich das verstanden habe, kann ich diese später einfach austauschen. Dadurch dass ich das Interface IDatabaseClient verwende bzw. dessen Implementierung, weiß ich, dass jede konkrete Fabrik immer genau diese Methoden (des Interfaces) enthält.
Die Business Objekte enthalten nur sowas:
public class User
{
protected String Name, Vorname, Benutzername... und die dazugehörigen geter und seter Methoden
}
Anmerkung: ja, bin dabei mich in die Muster einzuarbeiten, nur bin ich auch leider etwas unter Zeitdruck (das teil muss fertig werden...) und mein Prof will dass wir Entwurfsmuster verwenden. Ich denke/hoffe dass das Data Access Object Muster mit der abstrakten Fabrik hier doch passend ist.
LG
Hallo Daniel,
ich habe da etwas missverstanden. ich habe lediglich eine Klasse "User" geschrieben. Es ist aber noch eine DaoUser notwendig... auf jeden Fall ist jetzt alles ganz klar und ich kanns wunderbar benutzen.
Vielen Dank für deine Hilfe nochmals!