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?

4
  • 1
    Shouldn't there be some sort of type constraint on T? Maybe you could defer that the the implementations of EFileReader... Nov 3, 2014 at 23:07
  • Yes, that makes me uneasy. In implementation I would define T.
    – Matt
    Nov 3, 2014 at 23:09
  • Thinking about it more, so long as in the implementation T is defined or constrained a generic seems okay.
    – Matt
    Nov 3, 2014 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.
    – Matt
    Nov 4, 2014 at 1:49

1 Answer 1

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?

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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