The benefit of the Factory pattern is that it encapsulates the details of construction and specific type from how it is used. This allows you to evolve to more interesting designs later with fewer places to make a change.
Consider this example:
public interface IStorage
{
void Save(SomeObject toSave);
SomeObject Get(SomeId id);
}
public class DatabaseStorage : IStorage
{
public void Save(SomeObject toSave)
{
//persist to DB somehow
}
public SomeObject Get(SomeId id)
{
//get from db somehow and return
}
}
public class StorageFactory
{
public IStorage GetStorage()
{
return new DatabaseStorage();
}
}
public class DatabaseStorage : IStorage
{
public void Save(SomeObject toSave)
{
//persist to DB somehow
}
public SomeObject Get(SomeId id)
{
//get from db somehow and return
}
}
Now imagine you later get the requirement to cache some results, or to log all results. You could create a proxy, like this:
public class LoggingStorage : IStorage
{
private readonly IStorage _proxied;
public LoggingStorage(IStorage proxied)
{
_proxied = proxied;
}
public void Save(SomeObject toSave)
{
//log this call
_proxied.Save(toSave);
}
public SomeObject Get(SomeId id)
{
//log this call
return _proxied.Get(id);
}
}
Now, if you used a constructor, you have to replace every use of it to wrap it with this. If you used the factory, you only change it:
public class StorageFactory
{
public IStorage GetStorage()
{
return new LoggingStorage(new DatabaseStorage());
}
}
Of course, speculative factories can seem a little heavy handed for this, which is why I prefer to encapsulate the constructor.