2

I am trying to make use of SOLID principles for the first time. I am re-factoring a File class that stores file information and makes file operations available. This class is then inherited to specific file types to make available methods for that type.

I have started with SRP and have tried to make a FileWriter and FileReader abstract class to read and write from different resources. Some include:

  • File System
  • Streams
  • Database
  • Other undefined services (SOAP, REST??).

I am happy to say that the file data is handled by a byte array, but I am not sure how to handle the file path/uid for a resource.

Here is what I have...

public abstract class EFileReader
{
    event EventHandler<IEFileEventArgs> ReadThreadedComplete;
    public abstract byte[] Read(object source);
    public abstract async Task<byte[]> ReadAsync(object source);
    public abstract void ReadThreaded(object source);
    protected virtual void OnFileRead(IEFileEventArgs e)
    {
        EventHandler<IEFileEventArgs> handler = this.ReadThreadedComplete;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

I could cast the object as the required type in implementation. Alternatively it could be a generic type somehow specified in implementation (not sure how).

public abstract class EFileReader<T>
{
    event EventHandler<IEFileEventArgs> ReadThreadedComplete;
    public abstract byte[] Read(T source);
    public abstract async Task<byte[]> ReadAsync(T source);
    public abstract void ReadThreaded(T source);
    protected virtual void OnFileRead(IEFileEventArgs e)
    {
        EventHandler<IEFileEventArgs> handler = this.ReadThreadedComplete;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

...Or maybe there is some abstraction of the source I can write to accommodate the various possible use cases. I guess I could make it take an abstract FileResource class that exposes a stream.

What is the best way to approach this?

  • 1
    Shouldn't there be some sort of type constraint on T? Maybe you could defer that the the implementations of EFileReader... – FrustratedWithFormsDesigner Nov 3 '14 at 23:07
  • Yes, that makes me uneasy. In implementation I would define T. – Ablue Nov 3 '14 at 23:09
  • Thinking about it more, so long as in the implementation T is defined or constrained a generic seems okay. – Ablue Nov 3 '14 at 23:12
  • For DIP on a constructor passing the abstracted FileReader I need to make use of T in the class definition. This has a code smell I think. – Ablue Nov 4 '14 at 1:49
3

The whole purpose of creating System.IO.Stream in the framework, was to be able to handle data from different types of sources.

You should just make your source parameter a Stream type.

Also, you say your class handles data from different sources (including streams). This effectively no longer makes it a File class, doesn't it?

  • It should be a file regardless of the storage medium or transport protocol. It had data, name, extension and mimetype. – Ablue Nov 4 '14 at 8:58
  • Stream does sound like it would work. – Ablue Nov 4 '14 at 8:59
  • If a stream is used abstraction of read and write seems pointless – Ablue Nov 4 '14 at 9:31
  • Well, the framework already has StreamReader... – Rotem Nov 4 '14 at 9:38
  • Hahaha. So my refactoring hasn't really changed anything yet. – Ablue Nov 4 '14 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.