Wednesday, February 25, 2009

Coding is Easy - II

Yesterday I said Coding is Easy.

Some of the comments here and on reddit got me thinking a little bit (more).

I'll expand on that as it relates to the database world. First though, how do you measure code complexity? There has to be a scientific way, as compared to just stating, "This code is too complex." right?

Cyclomatic Complexity
...(or conditional complexity) is a software metric (measurement). It was developed by Thomas J. McCabe in 1976 and is used to measure the complexity of a program. It directly measures the number of linearly independent paths through a program's source code.

The concept, although not the method, is somewhat similar to that of general text complexity measured by the Flesch-Kincaid Readability Test.

Cyclomatic complexity is computed using the control flow graph of the program: the nodes of the graph correspond to the commands of a program, and a directed edge connects two nodes if the second command might be executed immediately after the first command.
Later in the Key Concepts section:
The cyclomatic complexity of a section of source code is the count of the number of linearly independent paths through the source code. For instance, if the source code contained no decision points such as IF statements or FOR loops, the complexity would be 1, since there is only a single path through the code. If the code had a single IF statement containing a single condition there would be two paths through the code, one path where the IF statement is evaluated as TRUE and one path where the IF statement is evaluated as FALSE.
In the database world, specifically Oracle (PL/SQL), your Control statements, IF/END IF, CASE, LOOP, etc. would increase the number of paths through the code.

Have you ever seen a CASE statement like this?
CASE
WHEN some_column = 'VALUE 1' THEN
do_something;
WHEN some_column = 'VALUE 2' THEN
do_something_else;
WHEN some_column = 'VALUE 3' THEN
do_something_else_thrice;
and it goes on for another 20 lines or more? Is this a good time to possibly rethink the underlying model? I say it is.

It may lead to the creation of another (lookup) table.

It may mean reorganizing your data in other ways.

It may mean absolutely nothing.

From Code Simplicity:
Often, if something is getting very complex, that means that there is an error somewhere far below the level that things are getting complex on.

For example, it’s very difficult to make a car move if it has square wheels. You’re going to be spending lots and lots of time figuring out how to make the car work, when really it should just have round wheels.

Any time there’s an “unsolvable complexity” in your program, it’s because there’s something fundamentally wrong with it. If the problem is “unsolvable” at one level, maybe you should back up and look at what’s underlying the problem. Maybe you put square wheels on the car, and now you’re trying to figure out how to make it go fast.

Programmers actually do this quite often. For example, “I have this terribly messy code, now it’s really complex to add a new feature!” Well, your fundamental problem there is the that code is messy. Clean it up, make the already-existing code simple, and suddenly adding the new feature will be simple.
At the risk of just quoting the entire Code Simplicity article...ah, who am I kidding? He says it much better than I could.
So when things get complex, back up and you look at the problem that you’re trying to solve. Take a really big step back. You are allowed to question everything. Maybe you thought that adding 2 and 2 was the only way to get 4, and you didn’t think about adding 1 and 3 instead, or just skipping the addition entirely and just putting “4” there. The “problem” is “How do I get 4?” Any method of solving that problem is acceptable, so figure out what the best method would be, for the situation that you’re in.

Discard your assumptions. Really look at the problem that you’re trying to solve, and think about the simplest way to solve that problem. Not “How do I solve this problem using my current code?” Not “How did Professor Bob solve this problem in his program?” No, just how, in general, in a perfect world, should that problem be solved? From there, you might see how your code needs to be re-worked. Then you can re-work your code. Then you can solve the problem.
Back up and take a look at the problem you are trying to solve.

Indeed.

A good design WILL make your coding less complex. In my case, that means a good data model.


For other references see:
Linux Journal, Programming Tools: Code Complexity Metrics
CodeProject, Cyclomatic Code Complexity Analysis for Microsoft .NET Applications
ONJava, Code Improvement Through Cyclomatic Complexity
Google, Let Me Google That For You

2 comments:

Anonymous said...

If you always code the same kind of things, of course coding is easy...

If you get to the point where it's easy for you to code anything, this is great, don't touch anything and enjoy! :)

oraclenerd said...

Not my point.

I'm saying the difficult part should be the design phase. And naturally that will change as you learn new and different things during the development cycle.

For example:
Initial design calls for a certain field to be required (NOT NULL). Through your development, or adding a front end, you realize, "hey, we can't make this NOT NULL just yet" and you remove the contstraint. That's simplifying it greatly of course...