Live data from Hacker News

Ask HN: How to avoid over-engineering software design for future use cases?

news.ycombinator.com

31–40 of 258 posts

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#31
post #10

The chapter The Second-System Effect form The Mythical Man-Month book (Brooks, Jr. Frederick P.) talks about this problem: “An architect's first work is apt to be spare and clean. He knows he doesn't know what he's doing, so he does it carefully and with great restraint. As he designs the first work, frill after frill and embellishment after embellishment occur to him. These get stored away to be used "next time." So…

Yet 'spare and clean' can mean breaking the problem down into primitives. And primitives can be reusable.

I agree, contriving baroque features and APIs are usually wasted time. But planning simple basic operations that others are built upon is good sense. When possible.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#32
post #18

> engineers go extreme in designing things/code for future cases which are not yet known They're afraid. Fear: If I don't plan for all these use cases, they will be impossible! I will look foolish for not anticipating them. So let's give into that fear and over-architect just to be safe. A bit of the 'condom' argument applies: better to have it and not need it than to need it and not have it. But the reality is that…

Also: have a framework in place, which supports worry-free refactoring. Comprehensive Unit/Integration tests, a robust type-system, pick whatever suits your style. It's a lot easier to refactor stuff when you don't have to worry about breaking something hard to debug with a big code change.

Unit tests are absolutely fantastic during refactoring. I once had to rewrite a piece of code where nobody really knew what it did or what it had to do, and the original author just made some guesses about the intention.

I started out by writing unit tests for everything, which became my handhold and documentation for what the system originally did. Then I started reorganising the code into a more structured and more readable form, without changing the functionality, as proven by my unit tests. Then I started asking domain experts what exactly it should do, unit tests in hand, asking if these answers were correct. If they weren't, I changed the unit test, and then changed the code to match.

Surprisingly painless for something that by all reasonable standards was a terrible mess.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#33

If there is an actual customer, try to get the scale of users/data the system is expecting. A system handling 1/1k/10M things every day will be quite different and need different solutions. Problems arise when people reach for the Cool Tools and start building Webscale things that can handle 100M operations every second. ...but the customer only needs the system to handle 4 users who type in everything crap by hand.…

How much time do you spend "making it pretty" after you've got it functionally working? Interested to hear your experiences on that.

For a long time we would "pretty it up at the end", in one of my coworkers words, which lead to a ton of horrible UX decisions early on that required major legwork later. We switched to doing ux-driven development from the start and it's saved us a ton of time and saved ourselves from poor decisions haha.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#34
Some of this is the experience to know what parts of a system are likely matter in the long run and some of it is the discipline to hold yourself and your team accountable.

If I had to boil the first part down, I'd say you need to focus your engineering on the interface points - network protocols, schemas, API sets, and persistence formats immediately come to mind. It's a truism of the profession that those are the most expensive aspects of a system to change, and therefore they're the least likely to be mutable down the road.

That's really the easy part... the harder part is maintaining the team and self discipline to keep things simple. For better or for worse, engineering job placement (and oftentimes personal satisfaction) is highly resume-keyword driven. Organizations and people all tend to chase the next resume keyword on the assumption that it'll help them deliver more efficiently or get the next job placement or write the next blog post or whatever else. The net of this is that there's a very strong built in tendency for projects to veer in the direction of adding components, even before considering whether or not they're appropriate for use. So keeping your eye on actual, real project requirements over all else is both important, and can require convincing and political work throughout a team and organization.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#35
It depends on the impact of the change to add flexibility in the future. A schema change to a table with many rows that could involve re-indexing usually makes me think harder about the initial data model and schema design. Refactoring code usually involves less cost and risk, especially with modern CI/CD practices, so I'm less likely to add a layer of abstraction if it's not required.

I've also found that designing for unknowns can sometimes be resolved by asking questions about the unknowns until they're known. Sometimes, business stakeholders have an answer, they just weren't asked.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#36

Data is the only thing that I personally care about "making future proof". Migrating data is a pain. Most everything else can easily be feature flagged or coded around. Even then, I don't dig too deeply into things. I look for two things: * What a migration path to realistically expected features _might_ look like. If I'm debating between two column types or table setups, go with the more flexible option. * What scen…

Really agree with your two bullet points. When I'm doing design reviews with people those are always the things I bring up. We're not going to actually design or build for requirements that we don't have yet but we can take a guess at what future high-level requirements might look like and use that as an input when talking about the current design.

An example of this conversation might look something like "This design is nice and simple but here are the possible scaling bottlenecks. If we need to scale X then what would be the path for that?" or "There's no reason to make this configurable now but if we needed to in the future how would we do that?"

Those sorts of questions shouldn't drive the design but if you're trying to decide between two designs that feel roughly as good as each other then it's a good way to tip the scale. I also find it a good way to introduce junior devs to thinking through those kinds of ideas.

One thing I had to learn to be careful with was to make sure it's really clear we're talking about future hypotheticals. I've had cases where the conversation about future design ideas ended with "Ok I'll go get started on that" and then we have to talk about how we weren't discussing real implementation changes, just hypotheticals about how the design might work in the future.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#37
Don't design your software for future features you might need. Design it to be easy to change. This means it has to be decoupled and simple. The trick is to make the software decoupled without making it complex. Adding layers and interfaces and abstractions is the easy way to achieve loose coupling, but it also adds complexity. Making software that's simple while still being easy to change is much harder than making some layer lasagna.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#38
post #10

The chapter The Second-System Effect form The Mythical Man-Month book (Brooks, Jr. Frederick P.) talks about this problem: “An architect's first work is apt to be spare and clean. He knows he doesn't know what he's doing, so he does it carefully and with great restraint. As he designs the first work, frill after frill and embellishment after embellishment occur to him. These get stored away to be used "next time." So…

[deleted]

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#39
post #10

The chapter The Second-System Effect form The Mythical Man-Month book (Brooks, Jr. Frederick P.) talks about this problem: “An architect's first work is apt to be spare and clean. He knows he doesn't know what he's doing, so he does it carefully and with great restraint. As he designs the first work, frill after frill and embellishment after embellishment occur to him. These get stored away to be used "next time." So…

Note that the Mythical Man Month was written a long time ago, and in the book the architect was more like what you would call a product manager today: they were in charge of the conceptual integrity of the system from the point of view of the user.

So while you can still draw parallels, just realize that this wasn't written about what we call architects today.

Re: Ask HN: How to avoid over-engineering software design for future use cases?

#40

Don't design your software for future features you might need. Design it to be easy to change. This means it has to be decoupled and simple. The trick is to make the software decoupled without making it complex. Adding layers and interfaces and abstractions is the easy way to achieve loose coupling, but it also adds complexity. Making software that's simple while still being easy to change is much harder than making…

> The trick is to make the software decoupled without making it complex

Any insights into how to do exactly this? Any rules of thumb or guidelines? Also what is not considered complex to some adds a cognitive burden to others.

Post reply on HN