AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Spring-DI / DelegatedConstructor / Factory für Dummies

Spring-DI / DelegatedConstructor / Factory für Dummies

Ein Thema von stahli · begonnen am 2. Feb 2012 · letzter Beitrag vom 15. Mär 2012
Antwort Antwort
Seite 2 von 10     12 34     Letzte » 
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.235 Beiträge
 
Delphi 10.4 Sydney
 
#11

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 9. Feb 2012, 12:25
Dann geht es dir wie dem Bauern, der keine Zeit hat, einen Zaun zu bauen, weil er die Kühe einfangen muss...
[OT]Ach das geht schon erst mal. Um die Weide ist ein kleiner Graben und wenn die Melkanlage erst mal auf vollen Touren läuft, dann schaue ich mir an, wie man am besten stabile Zäune baut [/OT]
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#12

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 9. Feb 2012, 13:04
Du weißt aber nicht, was du eigentlich verpasst, wenn du dich endlich mal um den Zaun kümmern würdest
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
631 Beiträge
 
#13

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 9. Feb 2012, 14:20
Ich glaube, dass eine wichtige Komponente von Dir außer Acht gelassen wird. Es gibt da nämlich noch die Haftung, die Du eigentlich mit den AGBs (Eula usw) bei kommerzieller Software (und bei OSS) ausschaltest. Wenn Du aber Deiner Sorgfaltspflicht nicht nachkommst, könntest Du in eine solche aber wieder geraten( siehe BGB). Und ein Unittesting könnte bei kommerzieller Software ein Richter schon als Sorgfalt auslegen(, meine ich, der zwar kein Rechtsanwalt ist, aber mit den Jungs viel zu tun hatte).
Gruss Jens
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
neo4a

Registriert seit: 22. Jan 2007
Ort: Ingolstadt
362 Beiträge
 
Delphi XE2 Architect
 
#14

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 09:56
Der (visuelle) Delphi-RAD-Ansatz, der den Einsatz mehrerer/vieler miteinander verknüpfter Komponenten bedeutet, steht einer vernünftigen, automatisierten Teststrategie entgegen.

Erzeuge ich dagegen die Komponenten aber bereits im Code, dann ist der Übergang zu DI-Containern sehr viel einfacher realisierbar. Damit ist auch die Ableitung eigener Komponenten inklusive Test viel leichter umsetzbar.

Angenommen ich habe z.B. 4 Panels, die auf einen Click reagieren sollen. Delphi-RAD: Ich weise jedem Panel sein OnClick-Event zu und implementiere dort den Ablauf. Unterscheidet sich der Ablauf nicht bis auf eine Kennung, so fassen ich die 4 Aufrufe vielleicht zusammen und werte den Sender in einer IF-ELSEIF-Konstruktion aus. Werte ich dagegen sogar das TAG-Property aus, vereinfache ich es noch weiter. So macht das wohl jeder irgendwann.

Was kann nun passieren? Bei einem 5. Panel "vergesse" ich das Onclick oder das Tag oder die Auswertung im OnClick.

Hilfreich kann schon eine solche Konstruktion sein:
Delphi-Quellcode:
constructor TMainForm.Create(AOwner: TComponent);
begin
  SetupPanelClick([pnlA, pnlB, pnlC, pnlD]);
end;

procedure TMainForm.SetupPanelClick(aPanels: array of TPanel);
var
  aPanel : TPanel;
begin
  for aPanel in aPanels do
    aPanel.OnClick := DoOnPanelClick;
end;
Diese Konstruktion sichert die visuellen Einstellungen im IDE-Inspektor noch einmal im Code ab. Der Aufwand ist gering, der Effekt dagegen hoch, insbesondere wenn es um zahlreiche Properties geht. Als Seiteneffekt gibt's damit auch einen Fehler, wenn einmal ein Panel versehentlich gelöscht wird.

Eines aber bleibt: Das Panel kann mir beim Setup nicht helfen, denn woher soll es denn wissen, wofür es da ist? (Mit GUI-Tests kann ich wenigstens nocht überprüfen, ob das Panel so reagiert, wie es soll.)

Erst wenn ich ein eigenes Panel ableite, das die Funktionalität beinhaltet, komme ich dem Testansatz näher: Ich verlagere die Funktionalität z.B. des "Geklickt"- Werdens in das Panel und gebe über ein Event und/oder Property das Ergebnis nach "außen". Das kann ich testen, da ist nichts komplex. (Da habe ich also meinen Zaun für die Kühe.)

Ich kann nun sogar mein Panel nun hinter ein Interface IMyPanel stecken und die Verwaltung einem DI-Container überlassen. So muss ich am "Einsatzort" keine spezielle Unit für TMyPanel einbinden, sondern nur die (zentrale) Interface-Deklarations-Unit. Damit habe ich ein gut entkoppeltes System, das leicht(er) testbar ist und bin auch noch flexibel: ich kann TMyPanel schnell durch TMyBevel ersetzen (wenn das IMyPanel implementiert).

Wer das bis hierhin gelesen hat, wird möglicherweise skeptisch anmerken, dass, wenn ich alles zu Fuß mache, ich ja gar keinen IDE-Designer mehr brauche. Stimmt wohl, letztlich läuft es darauf hinaus. Außerdem leben viele komplexe Komponenten-Sammlungen von automatischen Verknüpfungen, die auf RTTI basieren (leicht zu erkennen an Manager-Komponenten). Insofern:

Der (visuelle) Delphi-RAD-Ansatz, der den Einsatz mehrerer/vieler miteinander verknüpfter Komponenten bedeutet, steht einer vernünftigen, automatisierten Teststrategie entgegen.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
3.842 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#15

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 10:32
Der (visuelle) Delphi-RAD-Ansatz, der den Einsatz mehrerer/vieler miteinander verknüpfter Komponenten bedeutet, steht einer vernünftigen, automatisierten Teststrategie entgegen.
Da muss ich dir ausnahmsweise mal widersprechen. Es kommt darauf an, wie weit ich den RAD-Ansatz gehe. Ich sehe es bei uns in der Software, dass ich manchmal einen Frame aufmache und mich eine graue gähnende Leere anschaut und ich erst im Source rumwühlen muss, um zu sehen, wo welche Komponenten erzeugt und platziert werden. Das ist für mich persönlich der Horror. Wo man dann die Businesslogik implementiert, steht auf einem anderen Blatt. Und dort kann dann sehr wohl DI zum Zuge kommen. Dennoch würde ich niemals meine GUI im Source zusammen bauen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (10. Feb 2012 um 13:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.235 Beiträge
 
Delphi 10.4 Sydney
 
#16

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 11:04
Hi neo,

danke für den aufführlichen Beitrag. Das klingt an den meisten Stellen auch sehr plausibel und den Weg werde ich weiter andenken.

Allerdings sehe ich das wie Stefan, dass man GUI und BL getrennt betrachten sollte.

Die BL mit DI und Interfaces aufzubauen ist mit Sicherheit eine gute Sache und trägt zur Übersichtleichkeit bei der Projektwartung bei.

Die GUI würde ich aber (fast) immer in der IDE zusammenklicken wollen (außer in dynamischen Bereichen, die Abhängig von BL und Daten aufgebaut werden müssen).
In dem Zusammenhang ist dann natürlich eine gute Datenbindung hilfreich.

Insofern ist Dein Panel-Beispiel nicht ganz passend. Das Panel sollte nur als Userinface dienen, ohne selbst irgendwelche Zustände zu verwalten. Man könnte also z.B. ein Objekt an das Panel binden, dessen Eigenschaft ClickCount erhöht wird, wenn das Panel angeklickt wird. Weiterhin zeigt das Panel in seinem Caption die Eigenschaft ClickCount des gebunden Objektes an (sofern ein Objekt angebunden ist).
Dem Objekt ist es dabei wiederum wurscht, ob es irgendwelche Panels gibt, die gerade an es selbst gebunden sind.

Also sehe ich nicht die Notwendigkeit, GUI-Controls über ein Framework erzeugen zu lassen. In Bezug auf die BL- und Datenschicht begeistert mich das Thema aber immer mehr...

Nochmal zum Testen:
Stell Dir vor, in Deinem Panel-Projekt baust Du einen Timer ein, der nach 1 Stunde feuert und in dem Du versehentlich Panel3 löschst. Da kannst Du doch Unit-Tests durchführen wie Du willst und wirst das Problem nicht aufdecken. Die Panels, egal ob mit Ereignisbehandlungen oder Ableitungen werden "in sich" korrekt funktionieren. Aber im Zusammenspiel des gesamten Projektes treten dann doch Probleme auf, die nach 1 Stunde zum Tragen kommen.
Ich kann nachvollziehen, dass man mit solchen Tests bestimmte versehentliche Änderungen (Seiteneffekte) in einem sehr engen Umfeld abfangen kann, aber vermutlich ist das wichtiger, wenn man im Team arbeitet.
Ich denke, dass zumindest in meinen Projekten der Aufwand zum Nutzen in keinem sinnvollen Verhältnis steht.


Aber auf den Rest freue ich mich schon.


@Stevie
In Deinem letzten Satz stimmt etwas noch nicht... NO GUI?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.235 Beiträge
 
Delphi 10.4 Sydney
 
#17

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 12:47
Mal noch eine andere Frage, die aber auch in den Bereich mit hineinspielt:

Im Moment erzeuge ich diverse Objekte, die ineinander verschachtelt sind.
Eine Turnierveranstaltung enthält Turniere, die wieder Spiele enthalten, die wieder Spielparteien und zu spielende Sätze enthalten usw.
Über eine Iteration über Spiel.Owner..Owner..Owner kann ich ermitteln, zu welchem Turnier ein bestimmtes Spiel eigentlich gehört.

Ich verwalte also nicht explizit Spiel.Turnier als Eigenschaft. Über die (in einer Funktion verpackte) Iteration kann ich also für jedes Objekt bei Bedarf ermitteln, ob es in einem bestimmten Turnier enthalten ist bzw. zu einem bestimmten Turnier gehört.

Wenn ich meine Objekte künftig in einer Factory erzeugen lasse und daraufhin nur noch mit Schnittstellen arbeite, fällt diese Möglichkeit ja weg - oder?

Wie sollte man solche Beziehungen und Verschachtelungen am sinnvollsten verwalten?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
3.842 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#18

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 13:35
Dieses Owner Verketten verletzt ganz klar das Gesetz von Demeter. Dein Beispiel zeigt für mich ein gravierendes Designproblem. Sofern der angesprochene Code innerhalb einer TSpiel Klasse ist und diese implizit eine Abhängigkeit auf ein TTurnier hat, dann solltest du das auch dementsprechendüber eine TTurnier Eigenschaft in deiner TSpiel Klasse implementieren und nicht auf Implementierungsdetails an anderen Stellen (zum Beispiel über das Verketten von Owner) vertrauen. Wenn sich diese verändern, bricht dein Code an einer ganz anderen Stelle auseinander.

Hier auch nochmal der Hinweis: Unterscheide bei DI simple Datenklassen und Klassen, die wirklich Businesslogik übernehmen. Ein DI ist imo nicht dazu da, dir einen kompletten Objectgraph für ein Turnier, inklusive Austragungsorten, Spielen und Spielern aufzubauen (ich gehe hier davon aus, dass die besagten Objekte nur PODOs sind).
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (10. Feb 2012 um 13:45 Uhr)
  Mit Zitat antworten Zitat
exilant

Registriert seit: 28. Jul 2006
133 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#19

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 14:18
Ich bin in der gleichen Situation wie Stahli, arbeite also an allein an einem über die Jahre gewachsenem Projekt. Ich habe mich in letzter Zeit ebenfalls mit den hier besprochenen Teckniken beschäftigt und sie für mich verworfen. Das ganze Kram führt zu imo zu "over engeneering". Zu Spring habe ich eine Session bei der EKON besucht und diverse Literatur durchgeackert. Es ist mir gänzlich verborgen geblieben wobei mich ein solches Framework unterstützen könnte. Unit testing lohnt den Aufwand nicht, und Interfaces benutze ich nur wenn ich gezwungen bin mich mit COM zu beschäftigen. In meiner Software sehe ich keinerlei Mehrwert gegenüber abstrakten Methoden. Demeters Gesetz hat was für sich, als allgemeiner Ratschlag. Aber wer sich ständig dran hält schreibt sich die Finger Wund. Für (fast) nichts. Selbst Heiligtümer wie die GOF Patterns haben sich für mich als nur eingeschränkt nützlich erwiesen. Die eine oder andere Idee dahinter ist OK und lässt sich nutzen. Das war es aber auch schon. Wiederverwendbarkeit ist gut, aber um den alten Spruch zu bemühen: Was nach allen Seiten offen ist, ist vermutlich auch nicht ganz dicht. Offensichtlich schlage ich mich nur mit trivialen Problemen herum. Ich habe mich noch nicht in der Situation befunden, ein Problem nicht mit einer einfachen und klaren dem Anwendungsfall angepassten Objekthierachie lösen zu können. Es werden viele Säue durch viele Dörfer getrieben. Ich denke zu viele.
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.235 Beiträge
 
Delphi 10.4 Sydney
 
#20

AW: Spring-DI / DelegatedConstructor / Factory für Dummies

  Alt 10. Feb 2012, 14:34
Die "Objekte" sind von TComponent abgeleitet (damit sie einen Owner haben und ich sie ggf. auch in der IDE einrichten kann) und enthalten Daten und BL.

Will ich in einem Spiel ermitteln, ob es sich in einem Turnier befindet, nutze ich eine lokale Variable und eine externe (in einer gesonderten Unit abgelegten) Funktion.

Delphi-Quellcode:
function OwnerTournament(C: TComponent): TodTournament;
begin
  Result := nil;
  if C is TodTournament then
    Result := (C as TodTournament)
  else if C.Owner <> nil then
    Result := OwnerTournament(C.Owner);
end;
Im Spiel dann etwa:

Delphi-Quellcode:
procedure TodGame.Calc;
var
  MyTournament: TodTournament;
begin
  ...
  MyTournament := OwnerTournament(Self);
  if Assigned(MyTournament) then
    MyTournament.Calc;
  ...
end;
Auf diese Weise kennt ein Spiel zwar nicht unmittelbar sein Turnier, kann dieses aber bei Bedarf ermitteln und dort z.B. die Ermittlung der Platzierungen veranlassen (das sollte ja erfolgen, wenn ein Spiel neue Ergebnisse hat).

Für SOOO schlecht halte ich dieses Konstrukt eigentlich nicht.

Deinen letzten Satz kann ich nicht im Detail nachvollziehen. Sollte man BL-Klassen und Datenklassen getrennt definieren und erzeugen? Wo liegt der Vorteil?

Im Moment kann der User ein neues Projekt anlegen, was einem TodTournamentEvent.Create() entspricht. Einige SubObjekte werden dann automatisch (leer) hinzugefügt, z.B. Sportart und Ort. Diese SubObjekte können dann durch den User über bestimmte Formulare bearbeitet und gefüllt werden. Andere Objekte erzeugt der User bei Bedarf komplett neu (z.B. Vereine und deren Mitglieder).
Jedes Objekt beinhaltet seine eigene BL und kann sich bei Bedarf in seinem Umfeld zurecht finden. Starre Verdrahtungen gibt es aber kaum.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 20:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf