[Design-Frage] Datenverwaltung mit Interfaces und DB



  • Hallo an die Gemeinde,

    folgendes Problem bei der Entwicklung eines Teils einer Applikation liegt zugrunde:

    Ich habe hier 3 Klassen, die eigentlich nur Daten und Zugriffsmethoden kapseln:

    User
    Enthält Daten für die Anmeldung an die Applikation
    -> lokale Benutzerverwaltung

    ServerAccount
    Enthält Anmeldungsdaten für einen Server. Es kann mehrere Accounts geben. Diese sind ersteinmal unabhängig von einem User. Ein Admin (User mit extra Rechten) bekommt diese Account-Daten bspw. per Brief u.ä., legt sie in der SW an und kann sie den lokalen Usern zuweisen.
    Dabei ist es gut möglich, dass es User mit mehr als einem Server-Account gibt sowie User, die alle einen Server-Account nutzen.
    -> Serverseitige Benutzer-Verwaltung

    Key
    Enthält Key-Daten. Meldet sich ein User an der Software an, wird sein ServerAccount geladen und die Anmeldung am Server absolviert. Zurück bekommt er eine Liste von Keys, die für diesen ServerAccount auch gespeichert werden müssen.

    Diese 3 Datenstrukturen sowie ihre potentiellen Zuordnungen müssen lokal gespeichert werden . Auf welchem Weg, also ob in einer mySQL-DB, Oracle, als normale Datei oder was auch immer, soll mir völlig egal sein, da ich vorerst nur am Kern der Applikation arbeite.
    Dies bedeutet notwendige Definition von Schnittstellen (hier: abstrakte Basis-Klassen), die mir Funktionalitäten wie add, delete, get usw. bieten.
    Da die 3 Datentypen nur implizit voneinander abhängig und auch einzeln geändert werden können, habe ich mir auch 3 Schnittstellen überlegt: bspw. IUserAdministration, IExternAccountAdministration, IKeyAdministration.

    Da die Interfaces jetzt mehr oder weniger vermischt werden (Bspw.: changeUser ändert an einem User die Zuordnung zu einem ServerAccount) und auch den realisierenden Klassen der Interfaces diese impliziten Abhängigkeiten mitgeteilt werden müssten (Bspw: Änderung eines ServerAccounts über IExternAccountAdministration muss zwingend auch Änderung der User, die diesem Account zugeordnet sind, bewirken) stellt sich die Frage nach der Güte des Designs... und natürlich die Möglichkeit der Implementierung.
    Angenommen, nicht ich implementiere die Interfaces, sondern jemand anderes... dann hat dieser jemand keine Ahnung von der Logik, die dahinter steckt (ist ja auch nicht der Sinn von Interfaces). Er würde also die Funktionen im Rahmen des Vertrages realisieren, ohne von Abhängigkeiten was zu wissen...
    Man könnte natürlich erzwingen, dass jede Realisierung auch die beiden anderen Interfaces meines Kerns nutzt (bswp. IUserAdministration gibt mir ein Zeiger auf ein Objekt vom Typ IExternAccount.... ). Stellt sich wieder die Design-Frage...

    Hat jemand vielleicht eine Idee, wie ich diese Problem auflösen könnte? Oder mach ich mir nur zuviele Gedanken?

    Vielen Dank schonmal für's Lesen :-),
    Tim

    PS: Dass lokaler Account und Server-Account nicht diesselben sind, ist vorgegeben.



  • Du bist zu sehr auf "Ableitung" & "Vererbung" festgelegt ....

    Was meinst du genau mit Schnittstellen(Interfaces) ?

    Angenommen, nicht ich implementiere die Interfaces, sondern jemand anderes... dann hat dieser jemand keine Ahnung von der Logik, die dahinter steckt (ist ja auch nicht der Sinn von Interfaces).

    Genau dann, und nur dann machen Interfaces sinn.

    Interfaces sind eigentlich genereller. In c++ als sprachmittel sinds halt abstracte Klassen.
    Es koennen aber auch Stringdefinitionen sein. Beispielsweisse der connect string bei ner Datenbank ... am ende ist das auch ne Vorgabe, und damit nen Interface.

    Der aufbau von xml dateien, also die beschreibung dazu (dtd, xslt) sind auch sowas wie interfaces ....

    Um Leute in C++ zu zwingen, ein Object nach ner bestimmten vorschrift zu nutzen, braucht man keine abstracten Objecte. Jeder normale header macht das schon.
    Ob Polymorphie eingesetzt wird, entscheidet wer alles gewisse Vorschriften zu implementieren (und nicht zu nutzen) hat, bzw ob verhalten im programm dynamsich ausgetauscht werden soll. Nur dann ist vererbung das mittel der wahl.

    Also auf welcher ebene gibst du deine funktionalitaet weiter ?
    baust du dll's die deine Anwender (andere Programmierer) nutzen sollen, und hasst da klassen(auch abstracte Klassen als Interface) drinne, nagelst du die auf den compiler fest.
    Wenn das nicht willst, musst auf andere Interface ausweichen (strings, xml, COM ... etc) ausweichen.
    Koennen / muessen / sollen alle eh den selben kompiler verwende, bzw alle muessen deine libs soweiso neu uebersetzen (der unix weg) dann sind C++ interfaces gar ned so verkehrt.

    Ob die klassen nun voneinander vererbt sind, also ne gemeinsame Basis haben, wuerd ich davon abhaengig machen, ob du sie an irgend einer stelle gleich behandeln musst (gemeinsammer container, funktionsaufrufe ... ).

    Im detail sind aber noch viel dinge zu beachten ... nen fertigen design vorschlag wird dir keiner machen koennen ....

    Ciao ...



  • Danke erstmal für deine Antwort @RHBaum.

    Einen fertigen Design-Vorschlag erwarte ich natürlich nicht, mir geht es nur darum herauszufinden, ob meine Überlegungen (im schlimmsten Fall) Müll sind. Und dazu brauche ich weitere Meinungen, bspw. deine 🙂

    Also, um mal einige deiner Fragen zu beantworten:

    - Alle, die in diesem Projekt (was natürlich sehr viel mehr enthält) arbeiten mit demselben Compiler und sitzen auch recht nah beieinander 😉
    - Den Einsatz von dll's halte ich im Moment für übertrieben.
    - Unter Schnittstelle verstehe ich einen Satz von Funktionen, der mind. 2 Komponenten bekannt ist, wobei die eine(n) diese Funktionen für ihr Funktionieren benötigt/benötigen, während die andere diese realisiert/realisieren.

    Mir ist klar, dass jeder Header an sich schon Schnittstelle sein kann.

    Hier geht es um eine Implementierung von Komponenten, die auch zeitlich entkoppelt ist. Desweiteren kann es im konkreten Fall durchaus sein, dass einen xxxDatenbank-Instanziierung nicht klappt, und einen Alternative gewählt werden muss (Austauschbarkeit), ohne dass die Funktionalität der einen Komponente beeinträchtigt wird. Insofern würde ich schon das Konzept der abstrakten Klassen nutzen.

    Grüße, Tim



  • Sonst keiner einen Kommentar?


Anmelden zum Antworten