4 ms·
I don't agree with all of these, but I'll add a couple of my own: - The ultimate goal of software is to solve the immediate problem at hand. The secondary goal
by miki123211 6mo ago
I don't agree with all of these, but I'll add a couple of my own:
- The ultimate goal of software is to solve the immediate problem at hand. The secondary goal of software is to solve likely future problems with as little work as possible. Any bad design which is better on those goals than a good design is actually a good design.
- Make your interfaces easy to use correctly and hard to misuse. Think of how people unfamiliar to the project will interact with them, make the obvious way be the correct way.
- Correct code should be easy to write; suspicious code should stand out.
- Shift bugs left.
- Fixing a bug class is better than fixing a bug.
- Interfaces are harder to change than implementations. An ugly implementation is ok if it has the correct interface.
- Use comments and documentation to explain why the code is the way it is. If it feels like there's a simpler way to do it, but that simpler way wouldn't actually work due to a constraint some people may be unaware of, document that.
- Don't repeat yourself; when it comes to data. If you store a single fact in multiple places; those places will inevitably get out of sync, and that causes bugs.
- There's a cost to straying off the well-trodden path. Don't be afraid to do so when it's truly worth it, but don't underestimate that cost. Worse (boring) technology is often better technology.
- Think in terms of expected value. Think not "Is this thing worth doing?", but "Is this thing worth doing, compared to the other things we could be doing instead?"
- Even if you think you're smarter than everybody else, intelligence isn't always enough, some problems can't be discovered until they happen. Other people have worked longer on this problem than you have. Learn from their mistakes.
- Friction is the silent killer.
- dirtbag__dad 5mo ago> The ultimate goal of software is to solve the immediate problem at hand. The secondary goal of software is to solve likely future problems with as little work as possible. Not really. Today I learned of a story where a vibe coding PM deployed a vercel app, which was in its entirety a single react component that serves a banner, that was embedded via an iframe into an entirely separate web app, whose repo they have full access to, because they needed to get a modal component out the door, but were blocked because they “couldn’t upload the image to s3.” (They could just use the public/ or assets/ directory and have the cdn pick it up, too.) People do the most insane things when they are tight on time and don’t have the intuition to do a bit of research up front. If you ask them, they’re solving the immediate problem at hand. If you ask anyone else who interacts with their work, they’re disrupting our days/weeks/months/years when we have to step through systems that don’t know any better. If you have the muscle to plan ahead, even a little bit, which is usually just following the same pattern over and over again, then you are fine. In this world you are still optimizing for the now problem but you have also solved, to some and ideally a better degree, some future problems for free
- miki123211 5mo agoSo it seems that we agree? Solving the immediate problem should be the primary goal (otherwise you get overengineering), but the secondary goal is still important. It seems like that PM didn't consider the secondary goal at all, he achieved the primary one without considering anything else. Incidentally, this is a pattern agents often fall into. They're great task finishers, not so great architecture designers.
- dirtbag__dad 5mo agoI guess what I’m saying is that there is no “primary” goal, but rather a mix of things to consider, where it working at all as expected is just table stakes.
- locknitpicker 5mo ago> - Don't repeat yourself; when it comes to data. If you store a single fact in multiple places; those places will inevitably get out of sync, and that causes bugs. I find this principle to hold only superficially, and once subjected to scrutiny it breaks down. There is a reason why Don't Repeat Yourself (DRY) was superceded by Write Everything Twice (WET). There were far too many junior devs swearing nonsense such as how a DRY abstract class that is inherited by two concrete classes is simpler than two classes or even functions that do mostly the same thing. These junior devs rolled out convoluted abstraction layers in name of DRY that would make enterprise code blush. Moreover, these simplistic yet fundamentalist DRY tricks introduced coupling between components that are similar at a superficial level but semantically held no relationship. Instead of rolling out premature abstractions, code must allow duplications. Copying a class poses a far lower risk than dumping a sea of inheritance with a bunch of abstract classes and interfaces and generics. The job of a software architect is to save developers from themselves, and minimizing code is such a way.