Software Engineering Laws Everybody Loves to Ignore
netmeister.org
netmeister.org
> "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else."
It goes on to say that even six months is optimistically high.
Genuinely curious, is this true for most people? It feels a bit hyperbolic to me.
No, only poor engineers.
In fact, sometimes I'm surprised by what I did 7-14 days ago. But yes, I can get back into that code much more quickly than if I hadn't written it myself.
Personally, I can remember pretty much every line of some algorithms I wrote years ago, but I was doing some cleaning the other day and there was a month old abandoned branch I had no idea why it was written.
Written stuff is hard as you have a lot of context in your head, your voice intonation etc.; sometimes a lacking comma, or reversed order of words, or a typo like missing an "s" or "ed" for plural/past can derail me for a good while while re-reading old text.
Starting code changes, notice some bad code, wonder who the hell wrote that crap, have to find that nasty person.
Fire up 'git blame', check code lines in question, "oh that was me, seems it is not that bad after all".
My performance is like a wave, sometimes I'm riding it, sometimes I'm being overwhelmed by it.
I don't go into the code I wrote 6months ago knowing exactly what every line does, but I remember the broad strokes about what it is generally doing, where different logic will live, and it makes it much easier to jump back into code I wrote 6months ago vs code I've never seen before.
More than once I've thought I've run into a bug and figure out what the problem likely is, only to go into the code and discover that I already covered that case and the bug is something else entirely.
Most of the rewrites are because I had to do something awkwardly because some feature didn't exist in a library, or it was broken and I had to work around it. Then a couple of years down the road that bug or missing feature has been fixed and I can pull out the hacks and do it the elegant way.
The times when the code is painful to read is when I write scripts that are supposed to be used once and turn out to be reused several times (but not very often) and when the specs were not really well defined at the beginning of the project.
Admittedly I am data scientist not SWE and it is hard to compare the complexity of SQL code to the one of a programming language.
Sometimes I go back to old code and go “What was I thinking”. Other days: “Wow, I was on it that day.” In any case, write like a stranger will be fixing your code later. Six months later, the stranger is you.
As far as rule of thumbs go, I think it's a good one.
In my experience, understanding the code 6 months later isn't the challenge, but rather understanding why I made the set of decisions I did with regards to any tradeoffs I made when writing the code.
The best way I can think of to try and keep that from happening is to comment, comment, and comment some more. Specifically, I try to explain not just the HOW but the WHY of a certain approach that I took. The way I see it, if using a little more disk space for comments saves me a little time from having to try and remember why I did something 6 months later, I'm cool with that. :-)
The most-important context is used as the body of commit messages; the more-detailed but still very important context goes into comments directly in the source code. Other context (with regard to why certain decisions were made, things that are tradeoffs, why an operating point was chosen, things to be revisited, how data to support this decision was collected, etc goes into the bug report and a dated text file with the commit hashes and bug number, which makes digging it up later significantly easier: just grep your notes for the relevant bug numbers and commit hashes.
Keeping those very detailed text files has saved me more than once, and when I slip up and don't include information it often comes to haunt me later.
You do want context there (in the comments), but often greater context (detailed information, that may go out of scope, or not reflect the current implementation of something) should be preserved elsewhere so you know a year from now why you made a decision.
You could keep all the information in the comments and be disciplined about updating them. But when you want to understand something that has changed, you end up needing to remember to go looking in the correct commits for the comments you made at that time. I personally just prefer dated, static notes that won't change and are easy to grep.
In general, as I've adopted good conventions and know-how, I find code that I've written a few years ago quite readable.
It is understandable, not completely foreign, but a lot of the context around my previous decisions evaporated in the meantime.
I'm in the habit of focusing my in-code documentation on why I made a choice, and my out-of-code documentation on code structure. This is probably counter intuitive to most people (who do the reverse from what I've seen).
The reason I do this is twofold. 1) Code structure changes don't occur that often for me (I'm a feature-terse programmer, only add what I need at the moment), and when it does change I really should be documenting that at the API level, not in the code.
2) The reason I made decisions are usually only relevant when I'm actually changing previous code (do to encapsulation and abstraction).
This method means that when I revisit an old project, I have my out-of-code API Documentation open in live-edit mode, using it for structure reference and adjusting it for any changes I make, and I have my reasoning sitting directly above the code I'm about to change. It works out really well!
Unfortunately, in school we were pushed towards documenting the structure in code, and using something like doxygen to extract that. I find that an ugly practice... The structure is always visible if you're adjusting code, but you're reasoning usually isn't.
Similar to the "Bike Shed Effect" or Law of triviality.
If you start as solo dev and then expand, will your org chart resemble the architecture?
Can you plan your org chart by thinking hard enough about your architecture?
Don't shape your architecture, shape your org, then your architecture will follow.
More towards your question, having also been in a mildly successful startup, I think there is a certain amount of layering in your architecture that you can setup on day one (frontend vs backend), but so much success rests on execution and product fit and such that it's not worth wasting too many cycles overoptimizing the architecture if you aren't already opinionated on it. Go with the architecture that you can iterate rapidly with.
While I haven't been a solo dev, I'd ask myself the question "what work will I offload once I can afford to, and what architecture do I need to create so that next 1-3 persons able to work without a ton of my time?" Iterate from there.
Obviously you can't blame all that on software architecture, but it is a danger that comes with architecting an org in the same way as code, and expecting it to work once animated.
I've only seen this work well in highly-repetitive, relatively low-skill/knowledge required workloads. Not knocking the participants, but there was often little novelty or real troubleshooting involved in those projects (often troubleshooting was handed off to a specific individual or group and the regular staffers weren't responsible for it).
I see Conway's law as an equals relationship IMHO, not a cause. The side that can give ends up adapting to the side that can't. In newer business where the architecture isn't established of course the structure influences the design. As the architecture matures and is worth a lot of money to replace it sometimes switches the other way. This of course can kill a lot of big corp's and IMO one of the biggest reason they may seem less agile to startup dev's - they have so many use cases to handle and systems have grown so complex it is a lot of effort to understand yet alone modernize these architectures. Often as well because they have been successful for awhile the regulators/governments have caught up with them and they have obligations that aren't so easily depreciated in any replacement.
https://web.archive.org/web/20210223182140/https://www.netme...
Conway's Law suggests that each module maps to one team (or subtree of your hierarchy), but not that each team is mapped to only one module. You would have one team responsible for, say, your authentication service (assuming it is a singular service and not a collection of services) but that team may also be responsible for some other services.
If you have multiple teams responsible for the same module/service, then over time they will generally gather together under a new hierarchy or merge into one team. So if your authentication service is presently managed by teams under Alice and Bob (and this is a singular poorly decomposed service) then the following are typical outcomes:
1. Alice and Bob's will become co-leads (teams merging).
2. Alice and Bob end up with a mutual manager Charlie (new or shifted hierarchy).
3. Either Alice or Bob's team because the sole responsible team (shifted responsibilities)
4. Either Alice or Bob is placed above the other (similar to 2, but one gets a promotion).
5. You're lucky and Alice and Bob are able to coordinate their respective teams effectively despite the lack of common hierarchy (uncommon in the long run).
6. You're typical and Alice and Bob and their teams fail to cooperate and you have frequent fires that your all-stars put out (and likely caused) and get promoted for.
(1)-(4) are what Conway's Law suggests will happen in the end. Though it's impossible to say when, it usually happens after (6) becomes an embarrassment to someone.
I have no idea where you got "only", it was not in my comment or the one above that I responded to. "a way" was what the original comment used, and I was saying that it was true about modular design generally as well. Neither of us used "only", that is an invention of your reading and is a bizarre one.
- running a service that can scale based on load
www.netmeister.org took too long to respond.
I'm not claiming that he's wrong or unjustified to feel that way - just an observation :P