cplusplus.co.il

Designing for testability: factories

Posted on: 18/09/2009

When we approach the process of designing our software, there are many issues we must address in order to be succesful. One of these issues (and you are free to disagree) is: How will we be able to test (or debug) our hand crafted piece of code?

This post will attempt to at least provide one way of writing code that is a little easier to debug and test, by making use of the factory design pattern.

Suppose you were writing a program that works with some kind of an external resource, and it greatly depends on that resource functioning correctly. How would you be able to verify that your own program works as it should? If you check it with that resource and find out that something isn’t working right, how would you determine if its your own fault or a problem with that external resource?

The common way to handle such cases is by using stubs, mocks, dummies, etc. (wiki) to simulate that external resource. That way you can (hopefuly) be sure that the object behaves correctly, and any bugs you may encounter are your own.

The most important thing regarding this issue of testing, is to design your software in a way that will allow it to be checked and tested very easily. If you don’t pay close attention to this matter during the design phase, you may end up with something that seems working, but you have no easy way of verifying it.

One relatively easy way to build your application in a way that will alllow easy testing is by using factories. Instead of creating your objects through explicit constructor calls, you can just as easily use factory classes. I will show how this pattern can assist with testing in just a moment. Another thing worth mentioning about factories is that, as opposed to constructors, factories can let you have a polymorphic way to create objects (that means you get a “virtual creation” for free) – I will leave it to you to think where and why that feature can be useful.

Now, let’s look at an example to illustrate how the factory design pattern can be utilizied to allow easy testing of our program. Suppose you are writing a program that needs to communicate with a database object:

struct Software {
    Software ();

    Database *m_db; // use some kind of a handle..
};

Now, in the constructor of that software class you can do one of the following two things:

Software::Software () :m_db(new Database(...)) {} // 1
Software::Software () :m_db(DatabaseFactory::create(...)) {} // 2

The point of this article is that using the first way will limit you to always using an instance of the Database class (not even inheriting classes), which will make it terribly hard and annoying to change, while using option 2 leads to a much more flexible design: it allows you to very easily create a stub or mock instead of the Database object, or even return a subclass of Database (effectively having polymorphic creation).

Here’s a simple implementation of the DatabaseFactory that allow testing as well as normal use (and a little more):

struct DatabaseFactory {
    static Database *create (...) {
        #ifdef TESTING
            return new DatabaseMock(...); // subclass of Database
        #elifdef OPTIMIZE
            return new DatabaseOpt(...); // subclass of Database
        #else
            return new Database(...);
        #endif
    }
};

Ofcourse, you could make decisions regarding the creation proccess during runtime just as easily, instead of using preprocessor directives.

Note: I am well aware of the fact that in the given design, Database would most likely be an interface. But even so, I’ve seen more than one piece of code where the concrete implementor of Database would still be created in the mentioned manner. Also, the code is given as an example to demonstrate the idea, not necessarily to show a realife case.

Advertisements

2 Responses to "Designing for testability: factories"

It’s important to mention here dependency injection, which might require a little less coding effort.
Since I mostly program in Python I have it a little bit easier with mocking and dependency injection, so ymmv 🙂

Dependency injection is indeed a relevant term to this article. Thanks for the comment.

Altough I would like to mention that the given scenario is only an example.. The described technique should (and can) be applied to internal dependencies and mechanisms as well as to external ones.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: