Learning From Mistakes: Leaky Abstractions

On the project I’m working on I’ve had a requirement to store and read files from the file system. Alse the files had to be accessible from the web.

Having a gut feeling that the infrastructure may change as the business will grow, I decided to hide operations on the file system behind an interface:

public interface IFilesStorage {
    string StoreFile(Stream stream, string fileName);
    Stream GetFile(string virtualPath);
    string GetFileUrl(string virtualPath);
    string GetFilePath(string virtualPath);
}

As it looks, if someday I’ll need to switch from the file system to another storage mechanism, I’ll be able to do get the job done by writing another implementation of the interface. Right? Wrong! The requirement did come in - I’ve had to store the files in S3. And only then I realised that IFilesStorage is a leaky abstraction.

[Read More]

Dependency Injection Patterns

Choosing the right pattern for implementing dependency injection is an important task and can affect your class’s usability and functionality. In this post I’ll overview 3 patterns of implementing dependency injection - constructor injection, property injection, builder (Joshua Bloch’s pattern, not GoF pattern). For demonstration purposes we will work with a class called TextTranslator, that requires 3 dependencies: TextReader, TranslationService and TextWriter:

public class TextTranslator
{
    protected TextReader textReader;
    protected TranslationService translationService;
    protected TextWriter textWriter;    
}

The sample code will be written in C#, but the examples are applicable to Java and other object oriented languages.

[Read More]