Today's video was triggered by unnecessary complexity. Ironically, today's video nearly didn't happen thanks to unnecessary complexity. Windows Camera stopped being able to use my webcam, Logitech G-Hub failed to start, and Logitech Capture works, but the sound quality is awful...
I still have no idea why they failed. The underlying systems are so complex that it could be any one of a whole array of problems. All I can do is shrug my shoulders, and say "that's software for you..." as hours of my time evaporate into thin air.
It's a problem we software engineers create ourselves. Having limited time, we bolt software module on top of software module, and then bolt another one on top of that. Do this carelessly, and you end up with something that is way more complicated than necessary, making it fragile and a total nightmare to work with.
The fragile nature of such code results in frustrated users delivering mind boggling bug reports which, because they're overly complex, are hard to track down and fix. Getting anything done in this environment is painfully slow, making us feel frustrated and unproductive.
AR vs. GCC-AR?
Here's what triggered today's rant: Last week I added a new library to ZitaFTP to expand its capabilities. I used GCC's ar(chiver) tool to create a static library file... and got linker errors. Weird. Was it reading the wrong file? No. Did I mess up the static library? Doesn't look like it. Have others had a similar problem? Let's do an internet search.
I finally stumbled on a website with the answer... an hour later. The ar tool doesn't work properly if Link Time Optimization (LTO) is enabled. Instead, I should use gcc-ar.
What!!? Why on earth is there a second version of ar to cover this case? This is a classic case of unnecessary complexity, where a task that should be simple is made unnecessarily complex (and poorly documented).
This Happens All the Time
The ar vs gcc-ar issue cost me an hour, but it's by no means the first encounter with unnecessary complexity. Using OpenSSL proved to be a nightmare. The task is relatively simple: encrypt data being sent via the network, and decrypt data being received. OpenSSL's API, on the other hand, is very difficult to use. The OpenSSL team may be working on this, but as of today, it's ridiculously complex.
How do We Fix This?
I don't have an easy answer, because writing good code is hard work. You'll likely be forced to use someone else's overly complex code at some point, in which case the best you can do is to hide it behind a simple interface.
Nevertheless, here are three suggestions:
1. Great software has the minimum complexity required to perform the task effectively
Try to keep things simple from the start, by keeping simplicity in mind when structuring your code. Remember, one switch has two states, two switches has four, eight switches has 256 states, 16 switches has approx. 65535 combinations, and 32 switches have round 4 billion combinations! Complexity can explode quickly, so limit how many switches and options you add.
2. Make the default settings "good" for the majority of users
If you must add configurable options for "power users," then at least make the default settings good. That way, most users don't need to get in under the hood and mess with things.
3. Add extra time for refactoring
Good software is like a good book; the first draft is usually very rough. Editing and refining is what makes it great. In software, this is called refactoring.
So, set aside time for refactoring. This may cause a fight with management, because they want software shipped fast. If that's the case, maybe you can add time to your estimates, and quietly do the refactoring with that extra time.
Reworking code to make it simpler and robust is essential for large projects, because, if you keep bolting things on top of each other haphazardly, then sooner or later you end up with an unmaintainable mess. You'll get more confusing bug reports from users that are hard to fix. Time to implement anything will increase, and you'll start regularly missing release dates. In short, maintaining the code would become a nightmare.
I'm sure others have good ideas on how to reduce code complexity. If that's you, please share it below. I'm always interested in writing higher quality code and becoming more productive.