Einzelnen Beitrag anzeigen

Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#1

(Abstract)Factory Pattern und Datentransfer

  Alt 4. Sep 2015, 10:34
Hallo zusammen,

sorry für das lange Posting.... Und gleich der Hinweis: Ich stecke noch in Delphi 7 fest - ich denke mit Generics wäre das einfach zu lösen..

ich versuch eine AbstractFactory zu implementieren, scheitere jedoch an den Details...

Ausgangslage:

Ich habe div. unterschiedliche PDF-Formulare zu füllen, als Beispiel:

* Bestellformular Firma A
* Bestellformular Firma B
* Reklamationsformular Firma C

jedes dieser Formulare liegt zudem in einer bestimmten Version vor, die ab einem bestimmten Datum eingesetzt werden muss, Beispiel:

Bestellformular Firma A
* Version 1 gültig ab 1.1.2014
* Version 2 gültig ab 1.8.2014
....

Bislang steckt der Code dafür in einer Klasse (je Formular) drin, die dann je nach Version unterschiedlichen Code ausführt, Beispiel:

Bestellformular Firma A

Delphi-Quellcode:
   ...
  if DruckDatum >= 1.8.2014 then
  begin
    ....
  end else if Druckdatum >= 1.1.2014 then
  begin
   ...
  end
  ..
Das schreit ja quasi nach dem Factory-Pattern. Also mal flugs umgesetzt. Damit das auch schön wird, gleich mit Interfaces gebastelt:

Delphi-Quellcode:

  IFiller = Interface
  ['{7F30E379-DC1F-433B-9C56-B79D5BDEC356}']
    procedure FillPDF;
  end;

  TFillerClass = class of TPDFFiller;

  TPDFFiller = class(TInterfacedObject, IFiller)
  public
    procedure FillPDF; virtual; abstract;
  end;

  TBestellformularFirmaA = class(TPDFFiller)
  public
  end;

  TBestellformularFirmaA_201401 = class(TBestellformularFirmaA)
  public
    procedure FillPDF; override;
  end;

  TBestellformularFirmaA_201408 = class(TBestellformularFirmaA)
  public
    procedure FillPDF; override;
  end;

  TFillerFactory = class(TObject)
  ....
  public
    procedure RegisterFiller(AClass: TFillerClass; AValidSince, AValidUntil: TDateTime);
    function GetFiller(AFiller: TFillerClass; ADate: TDateTime): IFiller;
  end;

Bei der Factory kann ich dann konkrete Implementierungen hinterlegen und dann in Abhängigkeit von einem Datum anfordern:

Delphi-Quellcode:
  FFactory.RegisterFiller(TBestellformularFirmaA_201401, StrToDate('1.1.2014'), StrToDate('31.7.2014'));
  FFactory.RegisterFiller(TBestellformularFirmaA_201408, StrToDate('1.8.2014'), StrToDate('31.12.2099'));

  ...

  Filler := FFactory.GetFiller(TBestellformularFirmaA, now);
So weit sind im Grunde auch alle Beispiele die ich zu dem Thema bisher gefunden habe


Mein Problem: Wie bekomme ich jetzt Daten in den "Filler"?

Lösung 1:
in die Basisklasse TBestellformularFirmaA kommen alle notwendigen Felder. Der Rückgabewert bleibt jedoch ein IPDFFiller, ein direkter Cast geht in Delphi 7 noch nicht. Hier müsste ich dann eine Funktion einbauen, die mir die Instanz der konkreten Implementierung zurück gibt, und dann nach der Abfrage einen Cast machen:

Delphi-Quellcode:
var PDF: TBestellformularFirmaA;
  Filler := FFactory.GetFiller(TBestellformularFirmaA, now);
  PDF := TBestellformularFirmaA(Filler.GetInstance);
"fühlt" sich aber irgend wie nicht so richtig an...

Lösung 2:
man könnte natürlich argumentieren, dass der PDFFiller eigentlich nichts mit den Nutzdaten zu tun haben sollte, d.h. dass es hier eine Datenhaltungsklasse geben müsste, die Datenfelder also nicht in TBestellformularFirmaA definieren sondern z.B. in TBestellformularFirmaA_Data - nur dann müsste ich im PDFFiller wieder eine Möglichkeit haben bel. Daten zu übergeben, dazu fällt mir aber auch wieder nur ein Typecast ein:

Delphi-Quellcode:
  
  IFiller = Interface
  ['{7F30E379-DC1F-433B-9C56-B79D5BDEC356}']
    procedure FillPDF(IData: Interface);
  end;
um das dann wieder in der konkreten Implementierung zu casten. Sieht mir aber auch nicht "richtig" aus.

Lösung 3: Für jedes Formular eine eigene Factory bauen - das wäre mit Generics nach meinem Empfinden recht einfach zu realisieren, in Delphi7 aber mit deutlich mehr Code und dem Aufwand in jeder Factory dann wieder casten zu müssen


Und jetzt meine Fragen:

* gibt es noch ALternativen bzw. was mich eigentlich bewegt: Was habe ich am Factory-Pattern nicht verstanden?

Grüße
  Mit Zitat antworten Zitat