Einzelnen Beitrag anzeigen

bepe

Registriert seit: 17. Okt 2006
118 Beiträge
 
#13

AW: Entkoppeln von Forms

  Alt 12. Sep 2017, 18:33
Das sieht ziemlich vertraut aus. Aber zusätzlich ist die Factory bei mir ein Singleton und wenn du keinen abgeleiteten Konstruktor verwendest, wäre mir TCreateFormFunction zu viel Tipparbeit .

Delphi-Quellcode:
interface

uses
  System.Classes,
  System.SysUtils,
  System.Generics.Collections,
  Vcl.Forms;

type
  IFactory = interface
  ['{D91ADAAF-971F-497F-8EDA-A4644BA33087}']
    procedure RegisterForm(AClass: TCustomFormClass);
    procedure UnRegisterForm(AClass: TCustomFormClass);

    function GetInstance(AClass: TCustomFormClass; AOwner: TComponent): TCustomForm; overload;
    function GetInstance(const AClassName: String; AOwner: TComponent): TCustomForm; overload;

  end;

function FormFactory: IFactory;

implementation

type
  TFactory = class(TInterfacedObject, IFactory)
  class var
    FactoryInstance: IFactory;

  class constructor CreateClass;
  class destructor DestroyClass;

  strict private
    FClassList: TDictionary<String, TCustomFormClass>;

  public
    constructor Create;
    destructor Destroy; override;

    procedure RegisterForm(AClass: TCustomFormClass);
    procedure UnRegisterForm(AClass: TCustomFormClass);

    function GetInstance(AClass: TCustomFormClass; AOwner: TComponent): TCustomForm; overload;
    function GetInstance(const AClassName: String; AOwner: TComponent): TCustomForm; overload;

  end;

function FormFactory: IFactory;
begin
  Result := TFactory.FactoryInstance;
end;

{ TFactory }

constructor TFactory.Create;
begin
  inherited;

  FClassList := TDictionary<String, TCustomFormClass>.Create;
end;

class constructor TFactory.CreateClass;
begin
  TFactory.FactoryInstance := TFactory.Create;
end;

destructor TFactory.Destroy;
begin
  FClassList.Free;

  inherited;
end;

class destructor TFactory.DestroyClass;
begin
  TFactory.FactoryInstance := nil;
end;

function TFactory.GetInstance(AClass: TCustomFormClass;
  AOwner: TComponent): TCustomForm;
begin
  Result := GetInstance(AClass.ClassName, AOwner);
end;

function TFactory.GetInstance(const AClassName: String;
  AOwner: TComponent): TCustomForm;
var
  tmpClass: TCustomFormClass;
begin
  if FClassList.TryGetValue(AClassName, tmpClass) then
    Result := tmpClass.Create(AOwner)
  else
    raise Exception.Create('Unbekannte Formklasse');
end;

procedure TFactory.RegisterForm(AClass: TCustomFormClass);
begin
  FClassList.AddOrSetValue(AClass.ClassName, AClass);
end;

procedure TFactory.UnRegisterForm(AClass: TCustomFormClass);
begin
  FClassList.Remove(AClass.ClassName);
end;
Die Registrierung würde ich eher direkt beim Form machen. Sonst wird mal was übersehen oder es kommt eine "riesige" Unit mit unzähligen Abhängigkeiten dabei raus.

Delphi-Quellcode:
  TMyForm = class(TForm)
  class constructor ClassCreate;
  class destructor ClassDestroy;

  end;
...
{ TMyForm }

class constructor TMyForm.ClassCreate;
begin
  FormFactory.RegisterForm(TMyForm);
end;

class destructor TMyForm.ClassDestroy;
begin
  FormFactory.UnRegisterForm(TMyForm);
end;
Und der Aufruf wäre wie gehabt: FormFactory.GetInstance('TMyForm', Self).Show;

mfg,
bp
  Mit Zitat antworten Zitat