Well having landed myself a new job I have a new set of challenges being presented to me. Some technical and some more directly related to humans.
This new job is a permanent position. The first permanent job that I've had in the last 2 years. I wouldn't have moved away from contract positions except for the compelling economic reason of the economy being a bit rooted. I'm settling into the job and finding myself surrounded by the same sort of problem code and problem systems that I've seen around for the last 5 years.
This is the first time though that I've seen so much broken and so many simple beautiful ways to fix the mess and yet I can see the path to a sane code base is going to be long with potential setbacks along the way.
The code currently consists of a number of software engineering anti-patterns and rather than make a list of the programming anti-patterns I can see I'll just list all of the ones mentioned in Wikipedia and make a note as to whether they are there or not:
Programming anti-patterns
- Accidental complexity: Introducing unnecessary complexity into a solution (YES)
- Action at a distance: Unexpected interaction between widely separated parts of a system (NO)
- Blind faith: Lack of checking of (a) the correctness of a bug fix or (b) the result of a subroutine (YES)
- Boat anchor: Retaining a part of a system that no longer has any use (YES)
- Busy spin: Consuming CPU while waiting for something to happen, usually by repeated checking instead of messaging (NO)
- Caching failure: Forgetting to reset an error flag when an error has been corrected (NO)
- Cargo cult programming: Using patterns and methods without understanding why (YES)
- Coding by exception: Adding new code to handle each special case as it is recognized (YES)
- Error hiding: Catching an error message before it can be shown to the user and either showing nothing or showing a meaningless message (YES)
- Expection handling: (From Exception + Expect) Using a language's error handling system to implement normal program logic (NO)
- Hard code: Embedding assumptions about the environment of a system in its implementation (NO)
- Lava flow: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences (YES)
- Loop-switch sequence: Encoding a set of sequential steps using a loop over a switch statement (NO)
- Magic numbers: Including unexplained numbers in algorithms (YES)
- Magic strings: Including literal strings in code, for comparisons, as event types etc. (YES)
- Soft code: Storing business logic in configuration files rather than source code (NO)
- Spaghetti code: Systems whose structure is barely comprehensible, especially because of misuse of code structures (YES oh god YES)
10 out of 15 anti-patterns. They obviously haven't been trying hard enough. Although honestly with the size of the code base and the amount of code duplication obscuring the business logic it's entirely possible that they have hidden some of the other problems in there.
To be honest it's the amount of code duplication and the extraordinary lack of libraries for repeated tasks that makes me the saddest. And discussing some of the issues with my fellow programmers makes me realise that the process of education is going to be a long one.
I've decided to concentrate on two main things:
- Code Reuse is a good thing - Don't repeat what you've done before because you'll never be able to fix it all again later.
- Database Abstraction Layers are a good thing in so many ways. Currently the codebase uses 3 different db access classes and has many hundreds of direct references to the database code. Oh and the SQL code is sprinkled liberally through the business logic code.
I think I'll have to make a conscious effort not to use this blog as a soap box to complain about bad programming but I think it'll come out at least some of the time. Once I find a good way to convince the other programmers of the idiocies of their ways I'll try to explain how I've done it here.