Einzelnen Beitrag anzeigen

Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#8

AW: Verständnisfragen zu Forms

  Alt 2. Jul 2013, 10:46
@Phoenix
Wow, das ganze bitte mal in Zeitlupe.
Könntest Du das bitte einmal an einem Beispiel verdeutlichen?
So grob in Pseudocode (ich hab Delphi seit Jahren nicht mehr angefasst und schreibe eigentlich nur noch Webanwendungen in C# und JavaScript):

Code:
method GetUserInput() // wird aus dem normalen Code heraus aufgerufen:
begin
  var ctlr := new UIController();
  ctlr.OnInputFinished := InputFinished;

  ctlr.GetInput();
end;

method InputFinished(sender, eventArgs)
begin

   // controller wieder aufräumen
   var ctlr = sender als UIController;
   ctlr.Dispose();
 
   // benutzereingabe verarbeiten:
   var input := (eventArgs as UserInputEventArgs).Model;
   ...
end;


// Klasse UIController:

using Form1, Form2; // Form 1 und Form 2 sind *strunzdoof* und geben nur ihre Events nach draussen. Sonst haben die absolut keine eigene Logik, so wie sich das für MVVM gehört

method GetInput() : passenderDatentyp
begin

  var dialog = new Form1();
  dialog.OnButtonClick := Form1ButtonClicked;
  dialog.Show();

end;

method Form1ButtonClicked(sender, eventArgs)
begin

  // form 1 wegräumen
  var form1 := sender as Form1;
  form1.Hide();

  var result := form1.ViewModel; // Datentyp des Viewmodels. Für Form1 liefert das nur zurück, welcher Button gedrückt wurde
  form1.Dispose();

  // optional je nach Eingabe weitermachen, EventArgs ist hier ein eigener Typ
  if (result.OKClicked)
  begin

    var model = new Form2ViewModel();

    var form2 := new Form2(model);
    form2.OnUserInputReady := Form2UserInputReady;
    form2.Show();
  end;

end;

method Form2UserInputReady(sender, eventArgs)
begin

  var form2 := sender as Form2;
  form2.Hide();
  var model = form2.Model;  // Formularstatus abrufen:
 
  form2.Dispose();

  // event auslösen das die Benuztereingabe fertig ist
  OnInputFinished(self, new UserInputEventArgs(model));
end;
Wie man sieht ist das ganze Eventgesteuert gehalten. Wenn die Formulare ggf. auf einem anderen Thread laufen blockiert da also nichts.

Mit einer leichten Anpassungen (hineingeben einer FormFactory in den UIController) kann man sogar die ganze Geschichte am Ende sauber Unit-Testen. Anstelle der echten Factory die die echten Formulare erzeugt würde dann eine TestFactory reingegeben, die beliebige Test-Eingaben auf die Models schreibt und dann die events auslöst. Die echten Formulare hingegen können auch mit Test-Models bestückt und getestet werden.

Der UIController muss lediglich die Formulare (besser noch: Nur Interfaces der Formulare) kennen.

So schreibt man entkoppelten und Testbaren Code. Klar kann man auch alles in Form1.OnButton1Click reinbolzen, aber eine saubere Anwendungsarchitektur dankt es einem hinterher, wenn man das nicht macht.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat