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:
- Socket Instanz wird im Constructor übergeben und der IO-Handler ruft dann selbstständig Send
auf
- 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