Chi è il responsabile del posizionamento del flusso?

3

Gli esempi in questione sono c #, ma si applica a qualsiasi lingua.

Se hai una funzione che legge il contenuto da un flusso. Chi dovrebbe essere responsabile di garantire che la posizione dello stream sia corretta prima di leggere?

Il chiamante o la funzione che sta eseguendo la lettura?

per es.

Il chiamante posiziona lo stream:

    public byte[] ReadBytesFromStream(Stream inputStream)
    {
        using (var ms = new MemoryStream())
        {
            inputStream.CopyTo(ms);
            return ms.ToArray();
        }
    }

    public void DoThingWithStream(Stream stream)
    {
        // .. do some stuff
        stream.Position = 0;
        var bytes = ReadBytesFromStream(stream);
        // .. do some more stuff
    }

Il lettore posiziona lo stream:

    public byte[] ReadBytesFromStream(Stream inputStream)
    {
        inputStream.Position = 0;
        using (var ms = new MemoryStream())
        {
            inputStream.CopyTo(ms);
            return ms.ToArray();
        }
    }

    public void DoThingWithStream(Stream stream)
    {
        // .. do some stuff
        var bytes = ReadBytesFromStream(stream);
        // .. do some more stuff
    }

Il lettore che posiziona il flusso significa che posso richiamare la funzione più volte con lo stesso flusso e ottenere gli stessi byte.

Il chiamante che posiziona il flusso significa che

  1. È un po 'più di lavoro da preparare e se lanci il flusso molto spesso potrebbe esserci un grande riposizionamento in corso. Ma,
  2. Potrei usare la stessa funzione di lettura per leggere da un punto arbitrario nel flusso se lo volessi davvero.

Mi sono praticamente convinto che il chiamante dovrebbe fare il posizionamento, ma se questo è il caso allora ci sono circostanze in cui non dovrebbe ?

    
posta JamesT 28.11.2014 - 16:00
fonte

1 risposta

5

Il chiamante è responsabile di mettere il flusso in uno stato adatto per essere consumato dal lettore. Ci sono due ragioni principali:

  1. Non tutti gli stream supportano il riposizionamento. Devi impostare la proprietà Stream.Position solo se Stream.CanSeek . Altrimenti, otterrai un'eccezione. (consulta la documentazione Stream.Position ).

  2. "Leggere dall'inizio" è un caso speciale di semplice "lettura". In generale, è consigliabile scrivere le proprie funzioni nel modo più generale possibile (per quanto ragionevole, confrontare anche YAGNI). Se spesso abbiamo bisogno di un caso speciale, possiamo sempre aggiungere un wrapper di convenienza con pochissimo sforzo. Tuttavia, non è possibile ottenere una funzione generale da una funzione con involucro speciale (o richiedere il refactoring del codice).

    Soprattutto quando si crea un'interfaccia pubblica è importante rendere questa interfaccia componibile. Una possibilità sarebbe quella di passare nella posizione desiderata come parametro. Funziona in generale, ma non in questo caso specifico perché non ogni Stream.CanSeek .

E poi c'è anche il problema di evitare "azioni spettrali a distanza". È irrilevante ciò che fa la tua funzione fintanto che gli effetti sono contenuti all'interno di quella funzione. Tuttavia, la modifica dello stato non locale può portare a problemi di individuazione dei bug. Se le funzioni hanno effetti collaterali o mutano inaspettatamente i loro argomenti, questo dovrebbe riflettersi nel loro nome, ma certamente nella loro documentazione. In questo caso, è previsto che la funzione lettore avanzi la posizione leggendo dal flusso. Tuttavia, probabilmente non è previsto che il lettore ripristini per primo la posizione.

Se lavoriamo al contrario, possiamo trovare alcuni casi in cui il metodo del lettore dovrebbe impostare la posizione:

  • Nel contesto della tua applicazione, vorrai sempre leggere gli stream dall'inizio e leggere lo stesso stream più volte. Hai documentato il comportamento che, per comodità, il metodo del lettore ripristinerà per primo la posizione.

  • Il metodo è privato. Questa è una carta bianca per ignorare qualsiasi argomento che si riferisce alla "componibilità", dal momento che controlli tutti gli usi di quel metodo.

risposta data 28.11.2014 - 16:43
fonte

Leggi altre domande sui tag