2

Is it an acceptable practice to initialize physical/external resources from a constructor when the resource is needed for the object to do it's work?

For instance, let's say I wanted to create an object that proxies a durable message queue and that the message queue is a physical database table.

Would that make sense to create an idempotent constructor which physically create the table if it doesn't exist yet?

E.g.

IMessageQueue queue = new SQLTableMessageQueue('table_name', dataSource);

Perhaps a static factory method would be more appropriate? In that case, the table creation would occur in the factory method and the constructor would be free of such behavior.

IMessageQueue queue = SQLTableMessageQueue.create('table_name', dataSource);

I'm not too sure what would be an appropriate approach? Another idea I had was to use the Repository Pattern.

plalx
  • 399

2 Answers2

3

Usually constructors are not used to initialize external resources, there are few reasons,

  1. Testability - It would be very hard to create unit tests
  2. To be in compliance with SRP

You could always pass the message queue to the constructor where you use it.

class QueueProcessor
{
    private IMessageQueue _queue;

    public QueueProcessor(IMessageQueue queue)
    {
        _queue = queue;
    }
}

Yes, you can use a factory to create the queue

class QueueFactory
{
    public IMessageQueue CreateMessageQueue
    {
        return new SQLTableMessageQueue('table_name', dataSource);   
    }
}

With this approach you can easily mock the message queue for testing, and also it does comply with the SRP compared to constructing the queue within the constructor.

0

Google's C++ Style Guide asks you to refrain from doing work in constructors. Their arguments may or may not be applicable to your language. Testing on the Toilet's six-year-old advice #3 on how to write testable code by not doing work in the constructor still holds though.

If you search for it online you'll find tons, /*Programmers*/ is one place to start.