![]() |
Designfrage bei Klassemodellierung
Ich kann mich im Moment nicht so recht entscheiden, wie ich denn folgenden Sachverhalt modellieren soll. Würde mich daher mal interessieren, wie ihr an so etwas heran geht.
Ein Mitarbeiter kann einen Antrag via Formular tätigen, z.B. Antrag auf weitere Rollen. Dabei gibt es drei verschiedene Antragstypen: neu, ändern und Nutzer löschen. Wenn es sich um ein neu- oder ändern-Formular handelt, so muss der Mitarbeiter Rollen angeben. Zudem gibt es noch eine Zusatzoption, die weitere Pflichtfelder einblendet, aber eben nur, wenn diese Zusatzoption gewählt wurde. Nun will ich einen solchen Antrag in Klassen gießen und bin bisher zu folgendem Ergebnis gekommen:
Delphi-Quellcode:
(Die Einrückung symbolisiert die Ableitung)
Request = class abstract
DeleteRequest = class(Request) RequestEx = class abstract(Request) RequestNew = class(RequestEx) RequestNewEx = class(RequestNew) RequestEdit = class(RequestEx) RequestEditEx = class(RequestEdit) Jedenfalls habe ich das "persönliche Problem", dass die Klasse DeleteRequet komplett leer ist, da ich (bisher) noch keinerlei Zusatzfunktionalität benötige und auch nicht weiß, ob ich diese überhaupt noch brauche. Zudem entstehen somit sehr viele Klassen, da da beschriebene Beispiel imho noch sehr klein ist. Daher kam auch sehr schnell die Idee alle Klassen in eine einzige zu mergen, wobei ich eben dann eine Typ-Property einbauen muss und manche Properties für gewisse Fälle "tot" und unbenutzt sind. Wie handhabt ihr sowas? Lieber wenige, dafür angereicherte Klassen, oder eher mehrere einzelne, wie im obigen Beispiel gezeigt? PS: Das hier soll nicht in einem Glaubenskrieg ausbrechen! :stupid: Mir ist definitiv bewusst, dass man immer einen Mittelweg gehen wird. |
AW: Designfrage bei Klassemodellierung
Du willst verschiedene Klassen erstellen, die auf einen gemeinsamen Datenbestand (einmalig) unterschiedlich zugreifen?
Oder willst Du die erzeugten Objekte sammeln und speichern? Für den ersten Fall würde ich die Notwendigkeit nicht erkennen. Die unterschiedlichen Formulare könnten einfach unterschiedliche Angaben abfragen und die Daten unterschiedlich ändern (bzw. Methoden der Datenschicht aufrufen). Im zweiten Fall würde ich (wie von Dir angedeutet) spezialisierte Klassen ableiten. Was willst Du denn sonst mit den Objekten anstellen? Diese sollen doch keine eigenen Daten + Logik erhalten - oder? |
AW: Designfrage bei Klassemodellierung
Bei deiner Skizze fällt mir direkt ein "favor composition over inheritance". Schau dir in diesem Zusammenhang mal das Strategy Pattern an.
|
AW: Designfrage bei Klassemodellierung
Heyho,
also ich würde mir wohl als Erstes ein Hauptmodul basteln. Darein würden dann immer die benötigten Oberflächen geladen bzw die Anträge in deinem Fall (Factory-Pattern). Dabei würde ich auch wirklich lieber mehr Klassen anlegen, da soetwas meiner Meinung viel leichter anpassbar ist. Wer weiß, was später nochmal dazu kommt? Zusätzlich würde ich jenachdem noch ein MVC-Pattern (Model-View-Control) für die Daten benutzen. Das würde dann z.b. so ablaufen: 1. Anwender wählt eine Antragsart aus (ein View bzw. eine Oberfläche wird von der Factory erstellt und einem Model bzw. Datenspeicher zugewiesen) 2. Änderungen an der View wurden vorgenommen, View teilt dem Controller mit das Änderungen vorgenommen wurden, Controller updatet das Model und teilt allen anderen Views bzw. Oberflächen mit (z.b. wenn man mehrere Formulare auf einmal hat die miteinander zusammenhängen und ähnliche Daten besitzen) das sie sich aktualisieren sollen. 3. View wird nicht mehr gebraucht und geschlossen und von dem Model getrennt. Zwar ein großer Aufwand, jedoch sehr leicht anpassbar und die Daten sind von den Oberflächen getrennt. Dies habe ich z.b. bei einem dynamischen Suchdialog für eine Datenbank benutzt. Dort gab es ein Hauptformular, wo man mehrere Suchfilter anlegen konnte (verschiedene Views), diese wurden immer mit einem Model gekoppelt (welche den SQL-Teil beinhalten, also Tabellenname und Feldname zum Beispiel). Am Ende wurde dann anhand aller Daten der Models ein SQL-Befehl erzeugt. Jetzt muss ich nur noch die Models austauschen (was jeweils eine Anpassung von drei Zeilen ist) und kann den Rest weiterbenutzen. Die Views sind ja nur die Oberflächen, wie z.b. eine simple Textsuche. So das wars erstmal von mir...falls etwas unverständlich war einfach sagen :) Alaitoc Edit: Natürlich ist dabei immer die Frage ob sich der Aufwand wirklich lohnt bzw. man die Zeit dazu hat. Ich würde dir ja gern mal das Projekt zeigen, aber war ein Firmenprojekt. Vll. kann ich zumindest später mal ne grobe Klassenansicht zeigen. |
AW: Designfrage bei Klassemodellierung
Sehr interessante Frage.
Ich geh mal davon aus, dass deine Request-Klasse die Anträge nur repräsentieren und nicht darstellen, also insbesondere keine Formulare sind. Dann würde ich das so machen: - TRequest ist ne Klasse. - Neu, ändern und löschen sind Aktionen, die zu nem Aufzählungstypen werden. Die Wahrscheinlichkeit, dass da noch mehr dazu kommt, als diese drei ist gering ( ![]() - Es könnten Änderungen an den Feldern, Zusatzangaben, etc. geben. Deshalb solltest du hier eher Klassen nehmen. Entweder Subklassen oder Kompositionsklassen. - Sollte sich ein Löschantrag anders verhalten als ein Neu-Antrag, hast qu quasi das Problem, dass du zwei parallele Klassenhierarchien bräuchtest. Einmal die Hierarchie über die Aktion (Neu, Ändern, Löschen) und einmal über die Zusatzeigenschaften. Das ist quasi das Problem, das du in deinem ersten Beitrag darstellst. Die Lösung liegt, wie Stevie schon angedeutet hat, in der Komposition. Allerdings heißt Komposition nicht immer gleich Strategy-Pattern. Hier wäre das IMHO eher ne ![]() ![]() mfg Christian |
AW: Designfrage bei Klassemodellierung
Zitat:
![]() Zitat:
Zitat:
mfg Christian |
AW: Designfrage bei Klassemodellierung
Zum Hauptmodul:
"Hauptmodul" war wohl etwas übetrieben ausgedrückt, eigentlich meinte ich nur ein Formular an dem ich meine Klassenstruktur koppeln kann. Die aber durch alles andere ausgetauscht werden kann, einfach nur einen Bereich wo die Views dargestellt werden bzw erzeugt werden oder Ähnliches. Zur Factory: Nun jenachdem wieviele Formulararten es geben soll, bzw. in der Theorie dazukommen könnten finde ich es angenehmer wenn diese einfach an zwei definierten Stellen hinzugefügt werden. Also ein grobes Beispiel: "Benutzer fordert FormularXYZ an" "Factory erstellt FormularXYZ und gibt es wieder, zusätzlich erstellt sie vll. noch das Datenobjekt dafür" Meiner Meinung ist eine Factory einfach sehr übersichtlich :3 MfG Alaitoc |
AW: Designfrage bei Klassemodellierung
Es sind reine repräsentative Klasse, die noch um Controller angereichert werden. Aber damit hat es wenig zu tun. Es geht eigentlich nur darum, ob hier eine so präzise Vererbung sinnvoll ist, oder eben eher wenige Klassen mit mehr Optionen.
Ich könnte ja alternativ zu den obigen Klassen folgendes konstruieren:
Delphi-Quellcode:
Das wäre dann eine sehr fette Klasse, von der ich halt nicht immer alle Eigenschaften benötige, abhängig vom Typ. Ich erwähne hiermit ausdrücklich, dass das nun ein sehr krasses Beispiel ist, da ich nun alles erdenkliche in eine Klasse gepackt habe. Man kann die sieben obigen Klassen ja auch auf drei komprimieren, aber mit dem gleichen Effekt.
Request = class
Typ : Element of (Neu, Ändern, Benutzer löschen) Rollen : List of Rolle ZusatzOption : Boolean PflichtWennZusatzOptionTrueA : String PflichtWennZusatzOptionTrueA : Integer |
AW: Designfrage bei Klassemodellierung
Ich versuche meistens meine Klassen immer so zu stricken, dass nur Eigenschaften o.Ä. in der Klasse sind die ich benötige. Wobei ich da wohl auch mal von abweiche, jedoch meistens lieber ein paar mehr Klassen. Einfach nur wegen der Übersichtlichkeit und der Anpassbarkeit.
Am Besten ein Klassendiagramm erstellen und überlegen was sich noch ändern könnte, bzw. worauf man gefasst sein müsste...natürlich auch wieder Aufwand ^^ MfG Alaitoc |
AW: Designfrage bei Klassemodellierung
Zitat:
Muss mir jetzt unbedingt mal das Clean Code Buch durchlesen -- ich hab es schon ewig daheim liegen und bin noch gar nicht dazu gekommen da mal rein zu schauen... |
AW: Designfrage bei Klassemodellierung
Ich hatte gewissermaßen Glück und bei mir wurde in der Ausbildung viel wert auf sowas gelegt. Wobei ich gar nicht wissen will was ich noch alles falsch mache :3
Was man zumindest immer bei sich liegen haben sollte ist ein Buch mit Entwurfsmustern, finde ich äußerst prakisch :) MfG Alaitoc |
AW: Designfrage bei Klassemodellierung
Zitat:
- Ne Abstract Factory (GoF:87) ist gut, wenn man zusammengehörige "Familien" von Objekten hat. - Ne Factory Method (GoF:107) ist gut, wenn du in Subklassen auch subklassen einer abhängigen Klasse hast - Ne Factory Method ohne Vererbung hat zumindest noch ne Vorteil, dass man LazyInitialization machen kann oder Objekte cacht. Außerdem hat man den Vorteil, dass man die Implementierungklasse eines Interfaces bzw. einer abstrakten Klasse von der Verwendung entkoppelt und somit zu nem späteren Zeitpunkt ändern kann. BTW: Das alles trifft natürlich auch auch die obigen Factory-Varianten zu. Wie gesagt: Factory ist nicht schlecht. Aber dass sie einfacher oder übersichtlicher als ne stink-normale Initialisierung sein soll, sehe ich nicht. Zitat:
Auf der anderen Seite haben viele Klassen auch ihre Nachteile, die ich einfach auch mal in die Runde werfe: - mehr Klassen bedeutet mehr Klassen, die man Gedanklich auseinander halten muss und nicht verwechseln darf - Klassen die einfach auf -Ex enden sind ein Zeichen für ne falsche Herangehensweise. Das sagt nur "ich hab hier was, das kann mehr, aber was es mehr kann, kann ich nicht genau beschreiben". Wenn du keinen gescheiten Namen finden kannst, ist was konzeptionell faul. - Mit leeren Klassen ist es ganz ähnlich. Die bringen ein Mehr an Komplexität, helfen aber nicht. Siehe hierzu auch den Artikel, den ich oben verlikt hab. - Eine bestehende Klassenhierarchie schränkt dich auch in deinen weiteren Möglichkeiten ein. Wenn du schon abgeleitet hast, wir es schwerer nochmal anders abzuteiten. Wenn du Vererbung machst bedeutet das, dass du dir zu diesem Zeitpunkt schon Gedanken um weitere Ableitungen, etc. machen solltest. - Vererbung wird wie Stevie schon schön zitiert hat, gerne überverwendet. Die eigentliche Vererbung ist nämlich nur ein Teil (und manche sagen der unwichtigere Teil) von dem, was du machst, wenn du ableitest. Siehe heirzu: ![]() Zitat:
Zitat:
mfg Christian |
AW: Designfrage bei Klassemodellierung
Zitat:
MfG Alaitoc |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz