Wednesday, December 2, 2009

Don't Beat Software Into Submission

As a software engineer (read: code monkey) it never really surprises me that software can turn out really, really badly. Customers are always annoyed when software doesn't work perfectly but code is a particularly gruesome mess. It can be made horrendous with poorly applied principles, bad code design and faulty assumptions. My current employer is a particularly shining example of bad code design.

On a daily basis we code monkeys spend countless hours employing logical constructs in SQL statements to facilitate the use of a single page rendering class that provides no advantage when finally implemented. Without getting into detail, what seemed like a good idea at the time has actually proven itself to be a very, very bad idea... time and time again. And we put enormous effort into writing code to support this very bad idea because it's there and we must support consistency. In other words, the guy who had the idea is the person making the decisions.

If there's one thing in this world that really drags software down, it's programmers with egos.

And here are some of the principles I've been espoused to work under on a daily basis:
1/ The less lines of code there are, the better the code is
2/ Don't use multiple logical statements when they can be conjoined
3/ Ternary operators are powerful and should be used as often as possible
4/ Functions shouldn't be concise, small functions should be combined to create less code
5/ Business classes should extend the library class that they use the most functionality from
6/ Using memory is wrong, storing everything on disk makes the application much faster and more scalable
7/ Re-use code by creating utility functionality that has different behaviour depending upon the parameters being passed in

Since I've wasted many days grappling with a generically implemented con-joined temporary 'buffer' table structure implemented to work around a limitation in the page rendering class, I'm going to spend the last minutes of my day debunking every one of these points in the hopes that somewhere out there is somebody willing to listen to reason.

1/ Every piece of code has to be maintained. If you write the code as concise as possible, this limits the number of people able to competently maintain the code. This increases the overall development time, maintenance cost and decreases the amount of further development that can be achieved.
2/ The less lines of code the less flexible the code is because a single line with two purposes cannot be re-used for anything but the matching pair of purposes the line is written for. The more of this code you create, the less flexible your software becomes which leads to inevitable spaghetti code.
3/ Setting a variable in a ternary operator is a good thing if the condition is a function returning a true or false because then the cause is separated from the effect and can be re-used without the necessary understanding of the relationship between the cause and effect.
4/ Basic software principles identified in 1967: If your function is longer than a single page, it should be broken down. Read a book and listen to an expert.
5/ Classes performing similar operations should have common ancestry. This allows the developer(s) to read, understand and adapt business functionality without needing to understand the multiple, different, independent underlying library class implementations (which all have different member variables, error handling, return values, functions, thousands of lines etc. etc.).
6/ RAM is the fastest, simplest way to make your application run properly. Utilising RAM allows the developer to embed logic in program code rather than in database queries, meaning that an average database might be a single query with 4 table joins, rather than an 8 way union with each union containing 25 table joins. Programs written with simple data access and programmed logic are linearly scalable rather than the exponentially (un)scalable nature of complex database queries.
7/ This idea is fine for generic, non-business specific functionality like a linked list, array or XML transformation. When the functionality is business specific (like a checkbox operation, data formatting etc.) the amount of parameters or 'settings' required is ever increasing because no two operations are the same. So the utility classes are never complete and maintaining and utilising them becomes ever more complex again leading to unmaintainable spaghetti code.

There's a difference between an engineer and a programmer. An engineer finds the best solution while a programmer works at it until it can't get any better.

No comments: