Breaking free from IF statements

I never questioned myself am I using too much IF statements. But I did start to doubt myself, when I had to cover all IF nodes with unit tests. And I did what I usually do, look around does this bugs more than just me. It turns that I’m not the only one with urge to get rid of IF statements.

For starters I recommend to watch all of Misko Hevery talk in YouTube, really inspires to question yourself. At the same time I see some over-engineering risk factors, but that is in my holly opinion just a matter of taste.

So I will bring up one example in JavaScript. I’m creating a mobile application and i’m using Fuse for that. Which means I have to write business logic in JavaScript, which isn’t bad.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function CreateWallItem(t) {
    if (t.type == "Offer") {
        return {
            id: t.id,
            type : t.type,
            posted : t.posted,
            offeredBy: t.item.offeredBy,
            description: t.item.description,
            likes: t.item.likes,
            reviews: t.item.reviews,
            image: t.item.image
        };
    }

    if (t.type == "Comment") {
        return {
            id: t.id,
            type : t.type,
            posted : t.posted,
            text: t.item.text
        };
    }

    return {};
}

API call returns array of items, which has to be rendered on screen. Each item has its type, based on type I create new object by include or excluding stuff I don’t want to be passed around. And here it is, IF statements are crawling into the code base. Switching to the switch statement wouldn’t change the picture. Code just doesn’t look right.

So I came up with this solution. Create a handler, who will magically understand which type is passed in and what to do with it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function WallHandler() {
    var handlers = {};
    this.register = function(type, handler) {
        if (type in handlers) {
            return;
        }

        handlers[type] = handler;
    };

    this.raise = function(type, item) {
        if (type in handlers) {
            return handlers[type](item);
        }
        return {type: "na"};
    };
}

Handler is small and contains only two methods and dictionary.

register

Add type handler as anonymous function to the dictionary (handlers), where dictionary key is item type.

raise

Execute type handler, if it is located by item type in dictionary (handlers).

Create Walll handler

1
var wallHandler = new WallHandler();

Register type handler with anonymous function

1
2
3
4
5
6
7
8
9
10
11
12
wallHandler.register("Offer", function(t) {
    return {
        id: t.id,
        type : t.type,
        posted : t.posted,
        offeredBy: t.item.offeredBy,
        description: t.item.description,
        likes: t.item.likes,
        reviews: t.item.reviews,
        picture: t.item.picture
    };
});

Alter method CreateWallItem

1
2
3
function CreateWallItem(t) {
    return wallHandler.raise(t.type, t);
}

No IF statements, handler is handling everything. To add new item type, just register new handler.

This is one way how to do it, but I think this is in right direction.

Leave a Reply

Your email address will not be published. Required fields are marked *