Hallo Delphianer,
ich hoffe der Thread Titel ist nicht zu abschreckend. Ich konnte aber leider keine bessere Zusammenfassung finden.
Ich bräuchte etwas Hilfe bei der Erstellung meiner Interface- und Klassenstruktur. Mit meinem Programm soll es machbar sein, dass diverse Daten von mehreren an den PC, per USB/Netzwerk/whatever, angeschlossenen Geräten ausgelesen werden können. Hierbei handelt es sich nicht um irgendwelche Laufwerke (wie USB-Sticks, HDDs, ...) sondern um Eigenentwicklungen mit eigener Software und Hardware.
So gesehen noch nicht dramatisch, aber es ist nicht nur ein Gerätetyp, sondern es können mehrere sein. Demzufolge haben diese Geräte auch unterschiedliche Parameter und Daten/Werte die ausgelesen bzw. geschrieben werden müssen.
Also habe ich mich dazu entschlossen, ein
DLL System aufzubauen um das ganze problemlos(?) erweiterbar zu machen ohne die Hauptanwendung antasten zu müssen. Diese DLLs geben eine Interface Instanz
IDataCollector
zurück. Die
DLL ist dann also für das Sammeln der Daten von den jeweiligen Geräten zuständig. Das bedeutet, dass es pro Gerät (bzw. pro Hardware welche andere Parameter hat) eine
DLL gibt.
Das Speichern der Daten würde auch von der
DLL übernommen werden, da die Werte sehr wahrscheinlich auch in unterschiedliche Tabellen geschrieben werden müssen.
Hier bin ich aber auch für Anregungen offen und dankbar. Mir persönlich wäre z.B. eine einzelne
IDataSaver
Instanz lieber, die das Speichern in die Datenbank übernimmt. Eventuell könnte ich das so lösen, dass ich nur das Statement übergebe und die Interaktion mit der Datenbank wird in eine separate
DLL ausgelagert welche für alle gleich ist. Hier wäre dann aber der verwendete Server ein Problem wenn von bspw.
MSSQL auf PostgreSQL umgestellt werden müsste. Demzufolge dürfte auch hier wiederum nur ein Interface übergeben werden. Aber dann bin ich prinzipiell an dem nachfolgenden Punkt:
Jetzt zum eigentlichen Problem, welches aber eventuell auch die angesprochene Thematik des speicherns der Daten in der Datenbank lösen/vereinfachen könnte:
Die Daten die von den Geräten ausgelesen wurden, müssen ja auch mal wieder angezeigt oder geändert werden. Entweder direkt als Daten aus der
DLL oder später aus der Datenbank heraus. Jetzt stellt sich mir die Frage, wie ich das am besten löse. Jedes Gerät hat ja wie angesprochen seine eigenen Parameter/Werte. Nur wie kann ich es anstellen, dass meine
GUI so flexibel ist und sich daran anpasst? Es gibt ja alphanumerische Felder (TEdit) oder reine Integer Felder (TEdit oder TSpinEdit) oder eventuell auch Auswahlmenüs (TComboBox). Die Tabellen sind ja pro Gerät evtl. auch unterschiedlich, also müsste das über einen passenden Service geregelt werden der die benötigten Daten abruft.
Aktuell sieht es so aus, dass ich die Struktur zum Auslesen der Daten habe (s. Bild). Programmiert ist noch nichts, ich mache mir nur gerade Gedanken über den Aufbau.
Im Hauptprogramm gibt man an von welchem Gerätetyp die Daten ausgelesen werden sollen. Über eine Factory wird bestimmt, welcher DataCollector geladen werden muss. Diese Information erhält er wahrscheinlich aus der Datenbank, weil dort die
DLL mit Namen registriert werden muss damit sie geladen werden kann. Wenn der DataCollector geladen wurde, kann dieser seinerseits natürlich auch wieder weitere DLLs für die verschiedenen Anwendungszwecke nachladen. Das ist dann aber dem DataCollector überlassen. Er kann prinzipiell auch direkt mit dem Gerät kommunizieren. Wichtig ist nur die Rückgabe/Speicherung der Daten (bei der ich wie gesagt keine Idee habe wie ich das realisieren kann).
Ich hoffe ihr könnt mir da irgendwie unter die Arme greifen und mir helfen, dass Problem zu lösen.
PS: Das hier war mal so ein erster Entwurf wie das IDataCollector Interface aussehen könnte. Es ist nicht wirklich viel, weil ich den Rückweg auch noch nicht kenne.
Delphi-Quellcode:
IDataCollector =
interface
[
GUID]
function Collect: Integer;
function GetLastError: Integer;
function SaveToDataBase: Integer;
// Diese Procedure müsste eigentlich ausgelagert werden
function SaveToFile(
const FileName:
string): Integer;
// Diese Procedure müsste eigentlich ausgelagert werden
end;
Danke fürs Lesen und ich hoffe auf viel Input. Wenn Fragen aufkommen, dann bitte einfach stellen. Vielleicht habe ich ja im Eifer des Gefechts die Hälfte vergessen.