Einzelnen Beitrag anzeigen

RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#1

MVC - Wie korrekt zweites Fenster instanzieren?

  Alt 9. Aug 2012, 12:02
Hallo,

ich implementiere gerade erstmals eine leichtgewichtige Trennung von Logik und UI. Diese funktioniert bei mir folgendermaßen:

Die Logik ist gekapselt. Jede spezielle Logik-Klasse leitet sich von einer abstrakten Klasse ab, die das Interface zur Benutzung definiert. Diese abstrakte Klasse leitet sich von einer Basisklasse für alle Logiken ab.
Delphi-Quellcode:
  TLogicIntf = class(TObject)
    // Basisklasse für alle Logiken
  end;

  TMainIntf = class(TLogicIntf)
    // abstrakte Basisklasse für die MainLogic, welche das Interface für die UI definiert
  public
    procedure Foo; virtual; abstract;
  end;

  TMain = class(TMainIntf)
    // konkrete Implementierung der MainLogic
  public
    procedure Foo; override;
  end;
Für die UI gibt es eine Basisklasse und davon abgeleitet verschiedene spezielle Fenster:
Delphi-Quellcode:
  TView = class(TForm)
    // Basisklasse für alle Views
  strict private
    FRestorePos: Boolean;
    FRestoreSize: Boolean;
  public
    // Konstruktoren und Destruktoren
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property RestorePos: Boolean read FRestorePos write FRestorePos
      default True;
    property RestoreSize: Boolean read FRestoreSize write FRestoreSize
      default True;
  end;

  TMainForm = class(TView)
    // erste spezielle View
  strict private
    FMainLogic: TMainIntf;
  strict protected
    property MainLogic: TMainIntf read FMainLogic;
  public
    constructor Create(AOwner: TComponent; AMainLogic: TMainIntf); reintroduce;
  end;
Und dann gibt es eine Klasse TLoader, die momentan ein Ladefenster zu Programmstart zeigt und das Hauptfenster und dessen Logik instanziert:
Delphi-Quellcode:
  TLoader = class(TForm)
    LoadLbl: TLabel;
  strict private
    FMainForm: TView;
    FMainLogic: TLogicIntf;
    FWindowsInitialized: Boolean;
  protected
    procedure DoShow; override;
  end;

procedure TLoader.DoShow;
begin
  inherited;
  if not FWindowsInitialized then
    // TAsync.Call: Die anonyme Methode wird aufgerufen, nachdem eine asynchron gesendete Windows-Message angekommen ist, also wenn TLoader tatsächlich sichtbar ist.
    TAsync.Call(procedure
      var
        Handler: TEvtPropBool.TChangedEvt;
      begin
        if FWindowsInitialized then
          Exit;
        FWindowsInitialized := True;
        LoadLbl.Caption := 'Laden...';
        Application.ProcessMessages;
        FMainLogic := TMain.Create;
        FMainForm := TMainForm.Create(Application, TMainIntf(FMainLogic));
        FMainForm.Show;
        Hide;
      end);
end;
(Quelltext wurde gekürzt)
Bis zur Erstellung des Hauptfensters meiner Anwendung ist also alles klar und ich bin glücklich mit der Vorgehensweise. Da ich aber keinerlei Erfahrungen mit MVC oder ähnlichem habe, stellt sich nun folgende Frage:

Unser Programm stellt im Hauptfenster eine Auswahl an Projekten bereit, mit denen gearbeitet werden kann. Jedes Projekt soll in einem eigenen Fenster angezeigt werden. In die UI (TMainForm) gehört m.E. nur der ButtonClick, der zu dem Projekt gehört, was geöffnet werden soll. Im OnClick wird dann eine Methode der Logik aufgerufen, die das Projekt initialisiert etc. und letztlich auch das Öffnen des neuen Fensters anstoßen sollte. Die Logik kennt natürlich weder die UI noch den Loader (Controller). Wie funktioniert das Öffnen des neuen Fensters bei solchen Trennungen üblicherweise?
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."

Geändert von RSE ( 9. Aug 2012 um 12:52 Uhr)
  Mit Zitat antworten Zitat