AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Designstruktur eines Funktionsgenerators

Ein Thema von Headbucket · begonnen am 24. Jul 2014 · letzter Beitrag vom 1. Aug 2014
Antwort Antwort
Seite 1 von 2  1 2      
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 08:33
Hallo zusammen,

ich bin gerade dabei einen Funktionsgenerator zu entwerfen. Dabei kann ich mich leider nicht wirklich entscheiden, wie ich ihn am elegantesten aufbaue. Es soll später mal ein solides Produkt werden und vllt auch hier und da mal um Funktionen erweitert werden. Von daher muss die Struktur von Anfang an klar sein.

Ich habe mein jetziges grobes Design mal unten angehängt. Es entspricht der Designvariante mit einem PageControl.
Ganz grob die Funktionen:
Es soll verschiedene Modi (Wellenformen) geben, wie z.B. Sinus, Rauschen, Sweep, usw. Je nach gewählter Wellenform sollen natürlich unterschiedliche Regler angezeigt werden, wie z.B. Amplitude, Frequenz und Offset für Sinus. Start- und Endfrequenz für Sweep, usw. Ebenso soll sich auch das "Display" und die Anzeigen darin verändern.
Man kann die Parameter sowohl im Display (sind Editfelder), wie auch über die Regler unter dem Display ändern. Wenn ich im Display also z.B. 1000 Hz einstelle soll der Regler auch auf 1000 Hz rutschen.

Designvarianten, die mir bisher in den Kopf gekommen sind:

Mit Hilfe von PageControl/Tabs
Beim der Wahl eines Modi wird ein bestimmtes Tab unter dem Display aktiviert. Die Reiter des PageCOntrol werden mit Hilfe von "TabVisible := false" ausgeblendet. Das gleiche könnte ich nun auch mit dem Display machen.
Vorteil: Ich kann alles im Design-Editor entwickeln.
Nachteil: Es könnte irgendwann eventuell etwas unübersichtlich werden

Mit Hilfe von vielen Frames
Ich erstelle für jeden Modi jeweils ein Frame für die Anzeige und für die Einstellungen und lade diese beim Aufruf des Modi.
Vorteil: Es wird alles etwas besser getrennt und vllt übersichtlicher?
Nachteil: Ich habe für einen Dialog im Programm sehr viele Frames, was das Gesamtprojekt sehr aufbläht.

Alle Elemente dynamisch erzeugen
Ich lasse den Design-Editor links liegen und erzeuge alles dynamisch mit Quellcode. Hier könnte ich natürlich auch alles in eine Unit packen oder in viele verschiedene.
Vorteil: Alles ist ordentlich angeordnet
Nachteil: unübersichtlicher Programmcode

Wahrscheinlich gibt es auch noch ein paar weitere Methoden, an welche ich im Moment nicht denke.
Mich würde nun einfach interessieren, wie ihr ein solches Programm entwickeln würdet. Wieviele Units würdet ihr verwenden? Wie würdet ihr das Design umsetzen?
Es kann halt gut sein, dass noch der ein oder andere Modi dazukommt. Hier muss ich also flexibel bleiben.

Vielen Dank schonmal!

Headbucket
Miniaturansicht angehängter Grafiken
generator.png   generator2.png  
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 09:54
Warum sollte das Projekt mit Frames aufgebläht werden?

Im Gegenteil, du entzerrst und lässt Luft ab wenn du nicht alles in ein Formular packst.

Wenn sich bestimmte Teile auf allen Frames wiederholen, dann bau dir ein Basis-Frame von dem du die anderen ableitest.

PS: Zudem würde ich jede Form und jeden Frame immer von einer/m Basis-Form/Frame ableiten.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (24. Jul 2014 um 09:57 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#3

AW: Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 10:00
Tabsheets sind schon mal blöd, denn ab ca. 7 Funktionen wird das schnell unübersichtlich. Besser ist hier eine TreeView (auf der linken Seite) und Frames auf der rechten Seite. Pro Knoten ein Frame. Nun kannst Du deine Funktionen auch gruppieren, d.h. die Übersichtlichkeit erhöhen.

Die einzelnen Frames kannst du dann individuell programmieren, was die Übersichtlichkeit erhöht.

Ich würde allerdings noch einen Schritt weiter gehen, und jedem Funktionsgenerator eine Klasse spendieren, wobei jede Klasse eine Liste von Parametern exportiert. Die Parameter sind z.B. vom Typ 'Schalter/Boolean' und 'Wert/Double'. Vielleicht noch zusätzlich ein Auswahlfeld (Funktion 'A', 'B', 'C', 'D'). Ein einziges Frame übernimmt die Darstellung der Parameterliste, z.B. als untereinanderliegende Controls (CheckBox, Combo/Radiogroup und Slider/Eingabefeld). Da jeder Parameter auch Eigenschaften wie Min, Max, Caption, Default etc. exportiert, kannst Du das sehr elegant und vor allen Dingen uniform darstellen. Bei der individuellen Programmierung in Frames passiert es hingegen schnell, das sich das Layout der einzelnen Regler doch unterscheidet (weil man irgendwo eine Verbesserung vornimmt und die dann nicht auf alle Frames ausweitet z.B.)

Das Schöne an so einem Entwurf ist, das die Klasse selbst seine Position innerhalb des Treeviews angeben könnte. Weiterhin kannst Du jede Klasse in eine DLL packen und so deine Applikation beliebig -auch nachträglich- erweitern.

Statt mit abstrakten Klassen würde ich das mit Interfaces realisieren, dann könnte man weitere Funktionen auch mit anderen Programmiersprachen zur Verfügung stellen, so etwa:
Delphi-Quellcode:
Type
  IParameter = interface
    Property Caption : String;
    Property Value : OleVariant read get_Value write set_Value;
  end;

  IBooleanParameter = interface (IParameter)
  end;

  ISelectionParameter = interface (IParameter)
    Property SelectionList : IList read get_SelectionList;
  end;

  IDoubleParameter = interface (IParameter)
    Property Min : Double read...;
    Property Max : Double read ...;
    Property Default : Double read...;
  end;

  IFunction = interface
    property Name : String;
    property Parameter : IParameterList;
    function Value (X : Double) : Double;
  end;
Syntaktisch 100% ist das nicht, weil ich lange nichts mit Delphi gemacht habe. Als abstrakte Klasse geht es auch, nur dann bist Du an Delphi gebunden (was ja nicht per se schlecht ist).

Warum sollte das Projekt mit Frames aufgebläht werden?
Weil man doch nicht alles in eine Form schmeißen soll. SRP, OCP. Frames sind das visuelle Pendant zu einer Klasse. Pro Funktion eine Klasse => pro Funktion ein Frame. Stringentes Design, finde ich.

Ich sehe das eher als Übung, denn als ausgewachsenens Projekt. Die von mir vorgeschlagene Architektur ist etwas überkandidelt für diese Aufgabe, aber das Pattern eines erweiterbaren Pluginsystems sowie das Pattern eines Parameterlistenrenderers (der, der die Controls bastelt) ist für viele Aufgabenstellungen geeignet.

Ebenso wie das stringente Arbeiten mit Frames (Frame <-> Klasse).

Finde ich.

Geändert von Dejan Vu (24. Jul 2014 um 10:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 11:03
Warum sollte das Projekt mit Frames aufgebläht werden?
Weil man doch nicht alles in eine Form schmeißen soll. SRP, OCP. Frames sind das visuelle Pendant zu einer Klasse. Pro Funktion eine Klasse => pro Funktion ein Frame. Stringentes Design, finde ich.
Mein Kommentar war als Gegenfrage zur Aussage:
Mit Hilfe von vielen Frames
Ich erstelle für jeden Modi jeweils ein Frame für die Anzeige und für die Einstellungen und lade diese beim Aufruf des Modi.
Vorteil: Es wird alles etwas besser getrennt und vllt übersichtlicher?
Nachteil: Ich habe für einen Dialog im Programm sehr viele Frames, was das Gesamtprojekt sehr aufbläht.
Und dann schrieb ich weiter dazu:
Im Gegenteil, du entzerrst und lässt Luft ab wenn du nicht alles in ein Formular packst.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 11:29
Also ich würde auf jeden Fall für jeden Funktionsgeneratortyp (Sinus, Rechteck, wasauchimmer) eine Klasse erstellen. So kann man das dann schön erweitern. Zu jeder dieser Klassen sollte es jeweils eine GUI-Schwesterklasse geben, die z.B. von TControl abgeleitet ist und die ganzen Steuerelemente beinhaltet. Man kann die Steuerelemente im Code erzeugen, oder natürlich auch ein im Designer erstelltes Frame zurückliefern. Ich selber habe unter Delphi bisher eher von Hand von TCustomControl abgeleitet und die Steuerelemente dann per Code erzeugt, weil ich daaaamals 2006 unter Turbo Delphi mal Frames ausprobiert hatte und irgendwie Probleme mit Windows-Scroll-Messages hatte, die nicht ankamen. Seitdem habe ich Frames dann gemieden... (zumal mir nach wie vor keine aktuellere Delphi-Version zur Verfügung stand/steht... in neueren Versionen gibt es das Problem glaube ich nicht mehr, unter Freepascal ebenfalls nicht).

Generell orientere ich mich immer am MVC-Pattern. Ist für mich aber auch kein Dogma... Ich finde es hier z.B. schwierig, sinnvoll in drei Klassen zu unterteilen und würde, wie bereits beschrieben, nur eine Unterteilung in zwei Klassen vornehmen. Die gleiche Entscheidung hab ich bei unserem (ehemaligen) Praktikumsprojekt, das ich jetzt noch weiterentwickeln darf, übrigens auch gemacht, und bisher hat sich das bewährt.

Man kann es natürlich auch so wie Dejan Vu machen. Ich denke, das lohnt sich vor allem, wenn man vorher schon weiß, dass man es nur mit ganz bestimmten Parametertypen zu tun haben wird. Wenn die „Plugins“ dagegen sehr unterschiedliche Arten von Einstellungen haben, besteht imo die Gefahr, dass man Ende tendenziell die komplette VCL in Form von Interfaces neu erfindet.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Designstruktur eines Funktionsgenerators

  Alt 24. Jul 2014, 17:07
Mein Kommentar war als Gegenfrage zur Aussage:
[x] Ich werde zu alt.
  Mit Zitat antworten Zitat
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Designstruktur eines Funktionsgenerators

  Alt 25. Jul 2014, 08:21
Vielen Dank, dass ihr euch die Zeit genommen habt, mir zu antworten.

Dann hat sich mein Gefühl mit den Tabsheets also bestätigt. So richtig wohl habe ich mich damit nämlich nicht gefühlt, weshalb ich den Thread ja überhaupt erst erstellt habe. So werde ich die Sache wohl mit separaten Klassen in verschiedenen Frames umsetzen. Wenn es Sinn macht, werde ich diese von Basisframes ableiten.

Ich werde mir auch nochmal die Umsetzung mit Interfaces anschauen, was ja von Dejan Vu vorgeschlagen wurde. Hier bin ich allerdings noch nicht ganz fit, weshalb ich das wohl mal nebenbei als Übung machen werde.

MVC habe ich mir auch mal als Lesezeichen gespeichert und werde es mir bei nächster Gelegenheit mal anschauen.

Danke nochmal und schon mal ein schönes Wochenende!

Grüße
Headbucket
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Designstruktur eines Funktionsgenerators

  Alt 25. Jul 2014, 08:41
Wenn die „Plugins“ dagegen sehr unterschiedliche Arten von Einstellungen haben, besteht imo die Gefahr, dass man Ende tendenziell die komplette VCL in Form von Interfaces neu erfindet.
Das Plugin-Konzept bildet das Model ab, nicht die View. Insofern kommt die VCL hier nicht ins Spiel. Bei den Einstellmöglichkeiten ist die Anzahl der abzubildenden Datentypen/Einstellmöglichkeiten überschaubar
  • Zahlenwert
  • Boolean
  • Text
  • Einfachauswahl
  • Mehrfachauswahl
  • Komplexe Daten/Record
Wesentlich mehr fällt mir hier nicht ein. Beim letzten Punkt muss man etwas komplexer werden, da dann auch die Editoren über ein erweiterbares Pluginsystem erstellt werden. Ist aber alles keine Hexerei.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Designstruktur eines Funktionsgenerators

  Alt 25. Jul 2014, 13:53
Ich habe das so verstanden, dass du zur Laufzeit automatisch die View dazu generieren willst, also für jede Text-Eigenschaft ein Edit etc.

Wenn es nicht so gemeint war, sehe ich aber auch nicht wirklich den Vorteil, denn dann kann ich doch von der View genau so gut direkt auf die Properties des Models zugreifen.
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#10

AW: Designstruktur eines Funktionsgenerators

  Alt 25. Jul 2014, 15:14
Ich habe das so verstanden, dass du zur Laufzeit automatisch die View dazu generieren willst, also für jede Text-Eigenschaft ein Edit etc.

Wenn es nicht so gemeint war, sehe ich aber auch nicht wirklich den Vorteil, denn dann kann ich doch von der View genau so gut direkt auf die Properties des Models zugreifen.
Doch doch, das war schon so gemeint. Der Renderer besteht dann aus 5 (6, wenn man komplex wird) kurzen IF-Anweisungen. Nur programmierere ich die VCL nicht neu.

Delphi-Quellcode:
Function GetControlForParameter (aParameter : IParameter) : TControl;
Begin
  if aParameter is IBooleanParameter then
    result := TCheckBox.Create(nil)
  else if aParameter is IDoubleParameter then begin
    result := TScrollBar.Create(nil);
    // Set min/max etc.
    end
  else ...
Als ich schrieb 'insofern kommt die VCL hier nicht ins Spiel', meinte ich die Implementierung der Parameter, Funktionsgeneratoren etc. Das war von mir missverständlich ausgedrückt. Trotzdem ist es sehr einfach umzusetzen und kompakt, da es keine strukturellen Wiederholungen im Code der View gibt.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz