Einzelnen Beitrag anzeigen

choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#19

Re: Zugriffverletzung beim Verwenden von Interfaces

  Alt 16. Dez 2003, 12:35
So, erst einmal 'nen neuen Kaffe und nun geht's weiter
Zitat:
Das Problem mit solchen Konstruktionen ist eben der oberste Stream, denn der muß ja von einer ReadOnly Stream-Kette in eine WriteOnly-Stream Kette die Daten pumpen.
Bei der Erstellung eines InputStreams wäre zwar ein Wrapping denkbar in der Form
myStream:= WrappingInputStream(AnOutputStream); ähnlich, wie es beim FiFoStream geschehen ist, in diesem Fall müsste aber jeder OutputStream intern einen Puffer vorhalten, bzw ein Puffer-Stream zwischengeschaltet werden, was ich für wenig elegant halte.

Tatsächlich liese sich doch das gepufferte Kopieren einer Datei wie folgt Realisieren:
Delphi-Quellcode:
myInStream:= BufferedInputStream(FileInputStream('InFile'), 4096);
myOutStream:= BufferedOutputStream(FileOutputStream('OutFile'), 4096);
while not myInStream.isEOF do
  myOutStream.Write(myInStream.Read);
myOutStream.Flush;
myOutStream.Close;
(selbstverständlich sollte der Destruktur eines Streams selbstständig Close bzw Close zunächst Flush aufrufen. Auch optionale Parameter sind bei der Erzeugung von Streams, zB bei der Wahl der Puffergröße denkbar).

Diese Schleife bildet also das Bindeglied der Ein- und Ausgabeströme und kann ihrerseits in einer Hilfsklasse implementiert werden. zB
Delphi-Quellcode:
myConsigner:= StreamConsigner(AnInputStream, AnOutputStream);
while myConsigner.HasData do
begin
  myConsigner.ConsignData;
  Log('Transfered Bytes: %d', [myConsigner.DataCount]);
end;
das Flushen und Schließend der Outputstreams kann dieser Zusteller ebenfalls selbstständig übernehmen, da ihm durch den Eingabestrom bekannt sein sollte, wann keine weiteren Daten vorliegen...

Zitat:
Wichtig ist meiner Meinung nach das nicht jede Interface Klasse ALLE möglichen Operationen veröffentlich, sondern eher über Typcast's andere Interface Klassen unterstützt.
Das sehe ebenfalls als notwendig an, um eine möglichst lose Kopplung zu erreichen. Die Vererbung von Interfaces halte ich auch für eine sinnvolle Variante, obwohl die Signaturen so mitunter zu sog. God-Facades mutieren können...
Denkbar wäre noch der Einsatz von Interfaces für jede konkrete Klasse zur Abbildung deren speziellen Fähigkeiten, falls diese Funktionen doch einmal innerhalb eines Clients, im Wissen um diese Schnittstelle, benötgtigt werden sollten.

Zu bedenken bleibt, dass bei der Kaskadierung (wrapping) von Streams auch Zyklen innerhalb des so erstellten gerichteten Graphens kreiert werden können, die vermieden werden sollten. Leider lässt sich eine Prüfung auf die Identität nicht ohne weiteres in der Form
Delphi-Quellcode:
function TMyStream.IsSame(const AStream: IStream): Boolean;
begin
  Result:= (Self as IStream)=AStream;
end;
durchführen, weil Delphi das Konzept der vererbbaren Interfaces konsequent durchhält, so dass die gezeigte Methode IsSame(...) auch mit einer Referenz auf IInputStream aufgerufen werden kann. Es gilt aber weiterhin:
(Self as IStream)<>(Self as IInputStream) so dass über eine Methode GetIdentity in einem Wurzel-Interface nachgedacht werden sollte...
gruß, choose
  Mit Zitat antworten Zitat