Einzelnen Beitrag anzeigen

Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Klassendesign: Blockierender Constructor?

  Alt 3. Nov 2016, 11:43
Delphi-Version: 10 Seattle
Hallo zusammen,

ich re-designe grade eine Klasse, die eine Netzwerk-Protokoll-Schicht implementiert. Dabei wollte ich beim Klassendesign folgende Aspekte vereinen:
  • SÄMTLICHE Kommunikation soll über meine IO-Handler Klasse ablaufen (Send Methoden und Receive Events)
  • Die darunterliegende Socket Implementierung (nur blocking) soll austauschbar sein
Für eingehende Daten hatte der IO-Handler bisher eine Methode HandleData , an die der Benutzer manuell die Daten übergeben musste, die er mit seinem Socket empfangen hat.
Für ausgehende Daten hatte ich bisher zwei Ansätze:
  1. Socket Instanz wird im Constructor übergeben und der IO-Handler ruft dann selbstständig Send auf
  2. IO-Handler hat ein OnSend Event, was vom Benutzer implementiert werden muss
Nun möchte ich aber einerseits HandleData loswerden und anderseits, dass der IO-Handler selbstständig senden kann (also eher Ansatz 1). Sprich: Der IO-Handler soll "Besitzer" des Sockets sein.

Meine Idee war jetzt das Socket im Constructor zu übergeben und dann selbstständig zu pullen:
Delphi-Quellcode:
type
  ISocket = interface
    function Send(Data: Pointer; Size: UInt32): UInt32;
    function Receive(Data: Pointer; Size: UInt32): Integer;
  end;

  TIOHandler = class(TObject)
  private
    FSocket: ISocket;
  public
    constructor Create(Socket: ISocket);
  end;

constructor TIOHandler.Create(Socket: ISocket);
var
  Data: array[0..1024 * 16] of Byte;
  Size: Integer;
begin
  inherited Create;
  FSocket := ISocket;
  // ..
  // internen Send-Thread erzeugen
  // ..
  repeat
    Size := FSocket.Receive(@Data[0], SizeOf(Data)); // blocking
    if (Size > 0) then
    begin
      InternalHandleData(@Data[0], Size);
    end;
  until (Size < 0);
end;
Meiner Intuition nach empfinde ich es allerdings als schlechtes Design im Constructor zu blockieren und komplexe Operationen auszuführen. Was sagt ihr dazu? Alternative wäre das Pullen in eine Methode auszulagern, aber dann habe ich wieder eine Art HandleData Methode, die extra aufgerufen werden müsste (was ich gerne vermeiden will).

Viele Grüße
Zacherl
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat