The book Pragmatic Programmer introduces the concept of programming by coincidence. In a nutshell it means writing code without really understanding what you're doing, how your snippet of code or app works. While everything seems to be working just fine on the outside, it might break later on for reasons unknown to you. I will break down the issue on this post, please correct me if there are obvious (or not so obvious) errors in the text.
Accidents Waiting to Happen
The concept itself has been broken down to following "accidents".
Accident of Implementation
Accident of Implementation might happen because of the way code's written. Maybe you're relying on some undocumented feature/bug of the library you're using, or some side effect that just happens when you're making your method calls in a certain order, without properly initializing your parameters etc. etc. In the end your relying on undocumented features or boundary conditions which just work with your code, but are breaking up often/easily when something else changes.
Accident of Context
Accident of context means that you create your code for a specific scenario but there are aspects you're not thinking of. You might be programming your modules assuming there's a GUI present, while that might not always be the case. Context accidents happen when you're relying on something that's not guaranteed to be there. I would also want to include copy-pasting code as a flavor of Accident of Context; if you're copying something (do consider DRY - don't repeat yoursef - as well), you need to be aware of both contexts, what do they have in common, how are they different.
Assumption Is the Mother of All F-Ups
Basically both of these accidents have their roots in assuming things. You assume that the code needs to be written in a way it is, you assume the API does what you think it does intentionally, even if it seems odd. You assume that your clients are literate and smart, that you know the context and environment in which the software will run. You assume your assumptions are correct :)
How to Avoid Programming by Coincidence
If there's a name for the problem and people have written about it, then there's bound to be a simple cure for it as well. Right? No. There are no easy step-by-step guides on how get rid of the issue once and for all. It takes conscious effort and focus to avoid this pitfall.
First and foremost, always be aware of what you're doing. Don't go on autopilot and make the easy assumptions. Look into things and how they work, test and document your assumptions for reference. Testing your assumptions and finding them wrong on the spot... That's a bullet dodged right there.
You should not program "blindfolded". Try to understand the basic concepts and what your (and all the related) code's about. Also, working with legacy software it's easy to take a look at the similar implementation for reference, or even copy-pasting it to get a head start. But try asking yourself a question: is there a reason why it was made like it was? Could you possibly improve the code base? The ones who come after you might want to thank you if you do!
Why am I writing this? As a reminder really, as I've recently bumped heads with hard to find bugs because of this very matter. Errors that could've been easily prevented if people would have paid attention to what they were doing. Everyone slips up sometimes, it's natural. Just try to be aware of what you're doing to minimize problems caused by programming by coincidence.
If you made it to the bottom, congratulations to you! If there's one thing to take in from the post, it's this:
Don’t Program by Coincidence