Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Allgemeines Interface (https://www.delphipraxis.net/162553-allgemeines-interface.html)

s.h.a.r.k 29. Aug 2011 09:53

Allgemeines Interface
 
Guten Morgen zusammen :)

Ich weiß nicht so recht, wie ich das Problem denn nennen soll, da ich noch nie so recht mit Schnittstellen gearbeitet habe. Bisher habe ich auch immer recht spezifische Klassen geschrieben, ebenso war das Applikations-Design nicht unbedingt allgemein gehalten. Das wird jetzt nach und nach geändert, ist ja auch im Sinne von OOP :stupid:

Ich habe im Moment folgende abstrakte "Startup"- und Applikations-Klasse, die ich für meine Anwendungen nutzen will -- TApHandledObject fügt einem TObject via AllocateHwnd nur ein Handle hinzu, um kommunizieren zu können.
Delphi-Quellcode:
TCustomApplicationController = class abstract(TApHandledObject)
private type
  TCustomStartupLoader = class abstract
  public type
    TCustomRequest = class abstract
    end;

    IRequestHandler = interface
      // GUID
      procedure Process(Request: TCustomRequest);
    end;
  private
    FApplicationController : TCustomApplicationController;
    FThread : TThread;
  protected
    procedure Execute(); virtual; abstract;
    procedure Request(Request: TCustomRequest); virtual;
  end;

private
  FStartupLoader : TCustomStartupLoader;
public
  constructor Create(); override;
  destructor Destroy();
end;
Ich habe folgende "Vision": der ApplicationController startet den StartupLoader-Thread der in der Execute-Methode -- asynchron zum MainThread -- alle möglichen Jobs erledigt, die die Anwendung zum Start benötigt: applikationsweite Einstellungen setzen, Log initialisieren, allg. Einstellungen laden, Datenbankverbindung aufbauen, evtl. auch Business-Objekte aus DB laden etc. Während des Startups zeigt der ApplikationsControlelr einen SplashScreen an, oder macht einfach gar nichts.

Was aber, wenn z.B. die Zugangsdaten für die Datenbank nicht korrekt sind? Einfach eine GUI einblenden kann ich ja nicht, da die Jobs ja asynchron zum MainThread laufen. Die Idee hier ist, dass der StartupThread ein Request an den MainThread schickt, dieser den Request entsprechend bearbeitet und eine Antwort zurück schickt.
Code:
MainThread --+--> Zeige SplashScreen ------------> Frage User nach ---------------------------------------> Zeige MainForm
             |                                ^    Zugangsdaten      |                                 ^
             |                                |                      |                                 |
             | Starte                         | Request              | Antwort                         |
             |                                |                      |                                 |
             v                                |                      v                                 |
       StartupThread --> JobA --> JobB --> Problem --> Warten ----------> Problem lösen --> JobC --> Fertig
Und hier will ich nun eine Schnittstelle bauen, die wie folgt agieren soll:
Code:
StartupThread ------------------> ApplicationController ------------------> RequestHandler
                TCustomRequest                           TCustomRequest         |
                                                                                | bearbeitet
                                                      <-------------------------+
                                                        und schickt zurück
Der StartupThread erzeugt ein TCustomRequest-Objekt, welches je nach Problem anders aussieht. In meinem DB-Beispiel beinhaltet dieses z.B. die Eigenschaften: Hostname, Database, Username, Password. Dieses Objekt schickt der StartupThread an den ApplicationController, der wiederrum eine Liste an registrierten Handlern hat und das Objekt an den passenden Handler weiterleitet. Implementiert dieser Handler das Interfac IRequestHandler, so kann der Request bearbeit und zurück an den StartupThread geschickt werden.

Klingt ja alles ganz schön und könnte so auch funktionieren, aber ist das auch okay so? Würdet ihr sowas anders lösen? Gibts Optimierungspotential?

ChrisE 29. Aug 2011 10:31

AW: Allgemeines Interface
 
Hallo,

Zitat:

Zitat von s.h.a.r.k (Beitrag 1120077)
Einfach eine GUI einblenden kann ich ja nicht, da die Jobs ja asynchron zum MainThread laufen.

Kommt sicher auf das Design an, aber du könntest dem Job ja diese Abfrage der Daten für die DB per Synchronized machen lassen. Dann kannst du die GUI schon aufrufen. Entspricht nach meinem empfinden dem KISS-Prinzip. Der Job für sich kann nicht fort gesetzt werden, ohne die Daten. Er muss also darauf warten. Somit auch auf eine Zeitscheibe des Mainthreads für die GUI-Aktionen.

Meine Sicht der Dinge.

Gruß, Chris

Stevie 29. Aug 2011 11:32

AW: Allgemeines Interface
 
Sieht mir ganz nach Command pattern aus.

Alaitoc 29. Aug 2011 12:46

AW: Allgemeines Interface
 
Ja das Befehlspattern würde sich hier sicherlich anbieten.

Der MainThread startet den StartUpThread, während er selbst in den Initialisierungs-Zustand geht (z.B. visuell dargestellt als Splashscreen).

So der StartUpThread führt nun alle ihm zguedachten Operationen durch, falls dabei irgendetwas am Mainthread geschehen soll, schickt er z.b. eine RequestUserData-Message an seinen Owner.

Dieser muss dann natürlich wissen wie er darauf reagieren soll, z.B. wenn er IRequestHandler besitzt.

Sobald dann die Submit-Message oder so kommt, wechselt der MainThread in den Initialisiert-Zustand.

Also eigentlich eine Kombination aus Command-Pattern und Zustandshandling, wie auch schon Stevie angedacht hat.

MfG Alaitoc

s.h.a.r.k 29. Aug 2011 12:51

AW: Allgemeines Interface
 
Ich hab irgendwie das Gefühl, dass ich all meine Problem von hinten aufrolle und alle Patterns "selbst" erfinde: Ich liefere ein Problem und bekomme Pattern-Vorschläge geliefert :mrgreen:

Danke Jungs! :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz