Question

Having read this question:

McCabe Cyclomatic Complexity for switch in Java

My interest went towards switch statements that cannot be solved in such a way (?).

Realising the McCabe decisions should be less then 20 to guarentee better maintainability I started to wonder about Win32 applications.

When making a Win32 application one can make buttons. Now as for these buttons, putting a handler on them is pretty typical and handling the message they send when they are pressed is often done in the Win32 callback function.

Now as an application grows bigger, this switch-statement becomes bigger (exceeding the 20). Does this mean that maintainability is worse for Win32 applications then others (Java Swing?)?

Or is this an exception to the McCabe complexity, and if so then in what way is this actually on par with the maintainability of other application types?

Was it helpful?

Solution

I don't think this has anything to do with Win32 applications per se. This has everything to do with using switch statements.

There is nothing preventing you for using a map, for example, that maps a message to a function that deals with that message.

In that case, as far as your code is concerned, there is no switch statement - just a map lookup, which means that your complexity should stay constant over time.

The reason you want this is because by using a map, you are effectively moving the "switch statement" from your code into the C++ standard library. McCabe's complexity is measuring your code. In other words, your logic is now simpler and the complexity score will show that.

Why is it measuring your code? Because the reason for the metrics is to assess the maintainability of the code and you are not going to be maintaining the C++ standard library.

Here's a very simple example:

#include <iostream> 
#include <map> 
#include <functional>

typedef std::map<int,std::function<void()>> ProcessMessageMap;   

void print_hi() {   std::cout<<"hi"<<std::endl; }   
void print_bye() {   std::cout<<"bye"<<std::endl; }     

enum Message {   SAY_HI = 0,   SAY_BYE,   DONT_DO_ANYTHING } messages;   

void process_message( const ProcessMessageMap &m, Message msg )
{
    auto i = m.find(msg);     
    if(i != m.end())
    {
        (i->second)();
    }
}   

void setup_map( ProcessMessageMap &m )
{
    m[SAY_HI] = std::bind(print_hi);
    m[SAY_BYE] = std::bind(print_bye);
}   

int main() 
{
    ProcessMessageMap msg_map;     
    setup_map( msg_map );     
    process_message( msg_map, SAY_HI );     
    process_message( msg_map, SAY_BYE );     
    return 0; 
}

You can see the output here: http://ideone.com/bq7HgT

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top