The dangers of black box development

For those of you who don't know what black box development is, I'll explain the concept a little first.

There are two main types of development, black box and white box; sometimes mixing of the two would naturally be referred to as grey box. Black box development is where the outside people have absolutely no idea what's going on inside, and it's basically a little magic box that'll churn out some sort of result. You can reverse-engineer the internals if you provide enough variable inputs and record their outputs for analysis, but generally, it's voodoo. The term comes from not being able to see in the dark; it's a void, like a black hole in the cosmos.

The opposite of black is white, so a completely open system is referred to as a white box. I've also heard glass box because of its transparency, but the balancing of colors is easy to remember. When you're developing a system, you usually understand all of what you're working on, so the system is transparent to you, hence a white box development.

The point in which something becomes a black box is when you decide not to peer into Pandora's box to see what's going on. You trust that the mechanisms are working correctly, and you carry on with your work. Typically, this is done when using external libraries or utilizing APIs. You don't know what's going on exactly because you just use them. You see the planets whirl around the Antikythera mechanism, but have no idea on even the number of gears inside it to make it work. I don't see any problem with treating external items as black boxes because it's usually out of your control to handle anyway. If you're using a proprietary third-party utility, then the best you can do is detect a bug in the output and account for it, but you can't easily fix the problem. The problem is when part of your own system becomes a black box for one reason or another. You, or someone on your team, is responsible for the contents of the box, and if you're also in the dark, then it's truly a mess.

This development type has been biting me for months with a current client of mine. The scope of the project is huge, and a lot of resources and hours have been put into it. It's a complete rewrite of an entire suite of applications to be under a single unified platform, so we're constantly reinventing the wheel when copying over functionality from the legacy system. There are a lot of dials and switches that can be tuned, triggered, and managed, but the real core of the application deals with pricing calculations. If the pricing calculations incorrect, the entire business goes under quickly. The importance of the calculations compounded with everybody on the development team, including me, insufficiently knowledgeable in the legacy system's calculations made everybody shy away from it. The team manager at the time told everyone to avoid the calculations and that he'd do it himself. This was a red flag immediately, but we had too much to do, too little time, and he had written much of the legacy system's calculations so we let it slide. He hadn't done any real development in a few years, being a manager, so he was sharpening his tools on this. The person with the least amount of development experience doing the most important work isn't something you want to happen, let alone him go away into his back office and do it without confirming with anyone else. To make matters worse, he was a staunch advocate of pair-programming.

For those unfamiliar with pair-programming, it's when two people sit down at a single computer, with a single keyboard, and program as a single individual. Sometimes there are benefits, like when you don't have a formal review process to double check the work, but it can become a hindrance a lot. He pushed hard for it, but couldn't get funding, and the team rejected. We would pair up on problems, but nobody liked the idea of pairing up full-time. He pushed, then he avoided. It was a classic example of someone not practicing what they preached.

I've had many "lock me in a dark room for a few days to work" moments and I've turned out some pretty amazing results from those times, but they're never perfect. If anyone says they did something right without anyone else seeing it, pounding on it, or basically testing it doesn't know what they're doing. The manager developed an entire subsystem by himself, over a couple weekends, starting over no fewer than 4 times (his own admission) because of the complexity, and all without any outside input. Then he walked in one day, dropped it on my desk and said, "Here, it's all done and tested. Hook it up." I hooked it up, and we didn't have any testers.

I had so many problems hooking it up that I get twitches thinking about it. He completely ignored all of our standards that he was the primary cheerleader for, and went completely askew with how we all agreed development should proceed. The fact that everything was "tested" made me wary given the huge unknown factor. Sure, I can test anything. I can honestly write a test for an addition mechanism that'll verify it'll never add two numbers together correctly, but it will be correctly tested and the tests will pass. Everyone saw the tests pass, and everyone was fine.

His design decisions while sleep deprived had huge ramifications for how everything worked. Everything was broken at first because of all the duct tape required to shoehorn things into place. As we began getting the system to work, everything was basically rewritten and his work disappeared, then he disappeared. Leaving the project, we were now on our own and couldn't rely on his domain knowledge. This is fairly common, and usually not a problem if a system is documented, but neither the old nor new system he wrote were documented at all. We knew the new system because we wrote it, but there was absolutely nothing documenting the old system. Everyone saw the tests pass, and everyone was fine.

The only part of his work that was left were the calculations, the moneymaker. I was the only one to deal with them regularly, and I started seeing problems. Every time a value was put into the system without any of the dials and tuners tweaked, it was fine. The moment anything was adjusted, all hell broke loose. Adding something as simple as a $5 fee of factoring in taxes made the number jump all over the place including going into the negative which would imply the company paying you to buy their stuff. We had a dedicated tester by now and bugs started rolling in. I wasn't the only one seeing irregularities in the calculations now; the testers saw them too. Everyone saw the tests pass, and everyone was fine.

I noticed multipliers and adjustments being applied twice and thrice based on different selections when they should only ever be applied once. I started seeing numbers disappear. I started seeing errors appear. I started seeing Tweety Pie fly around my head as I began to get dizzy. I raised some concerns and was referred to the tests. Everyone saw the tests pass, and everyone was fine.

I started playing around with the different segments. When tax was applied, exchanges were calculated twice, and when not applied, once. I filed a ticket, labeled it a blocker due to the severity of the system, and had to wait for it to receive approval to be addressed. We nearly launched as a beta with these calculation errors which worried me. The new manager kept ignoring the issue, referring to the tests. I showed the duplication in calculations, but was told to verify it in the old system because the tests passed. Everyone saw the tests pass, and everyone was fine.

I was handed a spreadsheet with "all of the variable calculations" that I had to use as reference, but when reading the file, it only had 10 results out of hundreds of permutations. I had to then reverse-engineer the legacy system to verify the calculations. The magnitude can't be understated because the legacy system was and is unmaintainable, hence the redevelopment. The golden reference spreadsheet proved incorrect and entirely useless, but nobody cared. I started cross-referencing the legacy calculations with the new ones, and every one was incorrect. The old system did calculations below a set price to factor in commissions, etc while the new calculations added them on. The entire approach to the calculations was incorrect from the start, but nobody noticed because he was in his own world doing black box development. Everyone saw the tests pass, and everyone was fine.

So I'm now sitting here, tasked with rewriting the entirety of the calculations system just because someone didn't want a second pair of eyes to analyze their work. They didn't want to be scrutinized. They developed in their own little world in a black box. Still, with all of the problems going for it, everyone saw the tests pass, and everyone was fine. That is, except me because I've been spending months reverse engineering what was done, and especially the last two weeks for the legacy system to compare with the new one.

So please, please don't develop in a black box when you're not working solo on a project. Your teammates will greatly appreciate it. Just simply ask for someone to take a look every once in a while. Don't get offended if your work isn't perfect. Always make sure someone goes over the work you do, either directly review it, or just review the functionality. If tests alone verify your work, make sure someone checks the tests.

Don't be that guy.

Everyone still saw the tests pass, and everyone was fine.

Copyright © 2004-2022 MecroMace LLC