'Over-engineering' is everyone's favorite punching bag, but I bet your codebase suffers from under-engineering instead
Posted by AtomicScience@reddit | ExperiencedDevs | View on Reddit | 202 comments
There is no shortage of articles and videos and whatever talking about the dangers of over-engineering, and there are plenty of catchy acronyms too - YAGNI, KISS, you name it. And while few of them are really wrong, I think the problem is with the fact that we focus on this problem much more than we should, all while neglecting under-engineering, which is much more prevalent and much more dangerous
I don't know about you (despite the clickbaity title claiming otherwise), but I can confidently say for myself - all the projects I worked on suffered from under-engineering, to a greater or a lesser degree. That was the real problem, and I can't really recall thinking 'Yeah, they surely wasted too much good thought on this one' - it was always 'Did anyone think at all when writing this?'
We all know how under-engineering manifests: sneaky shortcuts through architectural boundaries, god classes, accidental, implicit coupling, silenced compiler warnings all over the place - you name it
The main reason for under-engineered solutions is tactical programming - small, myopic changes that are done as system evolves, with little 'strategic' thinking
Yes, you need to be strategic even when doing the most seemingly tactical changes ever, because not only 'proper-engineering' is hard in and of itself, it has little tolerance for lapses too - you prematurely wrap up a task to end your day early, promise yourself to clean it up later (lol) and you just broke a window - and others will likely follow suit
Also, in a codebase that's deep into under-engineering territory, it's hard to bring yourself to do good work, because you will feel like a sucker cleaning up after all the 'tacticians' who've been here before - that's a textbook negative feedback loop
---
I understand why we mostly talk about over-engineering - it's easy to point fingers at guys who introduce load balancing for an internal admin service or whatever, there is always a clear villain in that case. But under-engineering creeps in at a pace so slow, you only realize you found yourself in a 'death by a thousand bandaids' situation when it's too late
Maybe I'm just too young and read too many smart books, and care a tad too much about shareholders' quarterly revenue, but isn't that common sense - you do diligent work on a weekday so that it doesn't come around and bite your ass on 3am Saturday or when you need to complete some 'needed yesterday' feature?
What do you think?
CoccoDrill@reddit
I've worked with an over engineered and under engineered code base. Both are equally evil. Simple don't over and under engineer đ¤ˇđźââď¸
vzq@reddit
It's overengineering when you anticipate requirements that never end up materializing. Otherwise it's just engineering.
davvblack@reddit
imo that's not even necessarily over-engineering! that's like saying, every part of the bullet proof vest is over-engineered except the spot that stopped the bullet. It can still be a "good wager".
It's over-engineered if the risk you would benefit from it, times the amount different the cost of execution is, makes it a worse tradeoff. And ESPECIALLY if the lifetime ownership of the overengineered solution is significantly higher, meaning that even if there's a 50% chance the added cost would be a benefit within three years, during that time features all take so much longer you could have just dealt with it when you saw it.
AtomicScience@reddit (OP)
When talking about anticipating requirements, indeed, it's all about the investor's mindset.
Suppose you know your product has a mere 10% chance of making it to where the complexity matters, but having to deal with 'simple' code then will be 50 times more expensive than paying paying a little complexity setup cost now
If you choose the complex solution now, you will be right. But paradoxically, that also means that with a 90% chance you will be wrong, and your bet will lose
After that, people call you 'that kind of people' and write blog posts about your 'over-engineering'
Federal_Decision_608@reddit
It's not a paradox, there is no code where it costs 50X to deal with complexity later.
donjulioanejo@reddit
On the other hand, look at it this way.
If only 10% of your projects get to a stage where you need complexity and extensibility...
It's a waste of resources making 100% of your products complex and extensible.
Keep them simple, and if one of them gets to a point where it actually needs to be complex, rewrite the damn thing from scratch.
You'll save resources in the long run.
yxhuvud@reddit
Or get good at rewriting in place. So, so many people are bad at refactoring.
WellHung67@reddit
Thereâs a middle ground, where you always add room for improvements later, so that itâs not a rewrite but more of a refactor. Depends on the project but you can find what little things now pay off the most potentially in the future, hit the low hanging fruit, and then isolate the hacks so you can replace them with something better the easiest way possible.
In short, kiss, yagni, but make it easier when you do actually need it for onceÂ
quentech@reddit
Yeah cause we all know how well that usually works out.
AtomicScience@reddit (OP)
Good luck with getting an approvement for a project that turned out to be a hit - all tasks will need to be completed yesterday, and the foundation you've laid during the project's infancy, when stakes were not as high, you are now stuck with it
Yes, that means overcomplicating 90% of the projects that dont make it, and that is a professional and responsible thing to do
edgmnt_net@reddit
It's also hard to justify spending a lot of money on an MVP just to end up scraping it. Because even bad/rushed coders cost a lot of money. And you end up pitching what, a steaming pile of crap? Showing you found some dudes who can code? In most cases your ideas aren't all that revolutionary to be worth that much on their own. The failure rate in that regime (say startups) is incredibly high, so unless you have a ton of money to bet on a hundred projects just to have 1 be a major breakthrough, this doesn't sound reasonable. Even if it did, isn't it more sustainable to develop a product more mindfully rather than gamble like that?
donjulioanejo@reddit
Granted, I work infra side, not code side... but even before I was a director, never had a problem doing it.
Set expectations early on. "We can deliver 90% of stuff quickly, but if we need to scale this particular thing, we need to refactor and/or rewrite the whole thing. We're happy to keep extending existing simple/shitty code, but keep in mind that it'll stretch each feature development from 1 sprint to 3 sprints as scaffolding needs to be put in place for every little thing. Let us spend 3 sprints rewriting it and then we can deliver quickly."
Rincho@reddit
It is actually an interesting risk paradox I read about.Â
The main office wants regional branches to take risks because that will be beneficial to the main office overall. But from a position of a regional branch director, taking risks is unwise because that can lead to your branch shutting down from series of bad decisions.
ALAS_POOR_YORICK_LOL@reddit
You don't need to rewrite, why would you even do that. Just evolve the design as you go
Maktube@reddit
Usually I agree, but sometimes it is as simple as "if we didn't know we'd need it, we shouldn't have done it". Usually in cases where your funding is limited and you need to release a product by a hard deadline. It doesn't really matter if your extra verification around user accounts would have saved you a lot of time in a year if you run out of money in six months.
I think there is a way to fit that into the way you worded it, really, (something something 0% chance of benefit something) but I'm too lazy to figure out the logic in my head :P
ContemplativeLemur@reddit
how many times I saw things like UserAddress turned into an AbstractConcurrentGeoLocation only to be used by a few dozen users
melgish@reddit
Those 15 optional parameters (and their resulting conditionals) on the function that only been called from one place for the entire decade of its existence will be important someday.
randylush@reddit
Or building a âserviceâ for a process that could be done by a high school dropout and a spreadsheet every week
a_library_socialist@reddit
There are some tasks where "ok, the intern spends 30 minutes a week" is the correct cost benefit solution.
shill_420@reddit
yep.
the business logic would probably look pretty crazy for those.
Head-Bureaucrat@reddit
I got asked to write an automated test once that involved very heavy data setup (different system feeding into ours, so I had to find existing data, and the business didn't trust that a mock or take would be accurate.)
Spent cumulative weeks trying to get the test working consistently with the data available.
Business manually tested it once a year, and it took them 30min for that system's BA to create the data and test it. I proposed we just scrap the automated test. Everyone agreed. Two years later a new manager came in and wanted that thing to have an automated test. After explaining the challenges, they wanted to try anyway. Rinse and repeat.
FitNerdDude@reddit
That's a wild take. You clearly missed the part of what software is purposed for. So you don't have to hire the HS drop out to do the weekly thing.
Dear_Revolution8315@reddit
wtf are you talking about. Iâll have you know our org has 15 processes that we pay six-figure engineers to waste time on every week
youâre telling me thatâs not money well spent???
FitNerdDude@reddit
And they can't handle automating a simple task that takes a HS dropout?
Interesting... Drop the name so I know not to waste my time applying. Actually, don't bother. I doubt this org can afford my base đ¤Ł
Dear_Revolution8315@reddit
Did the sarcasm not come across in my message? Guess tone is easily lost online.
Was agreeing with you.
FitNerdDude@reddit
You have my sincerest apologies.
It went over my head. My fault for context switching between all the things.
randylush@reddit
Found the volunteer lol
oldDotredditisbetter@reddit
those promotions aren't gonna promote themselves
anand_rishabh@reddit
Somehow it's always the things that i put a lot of planning and good coding practices into that get scrapped soon and the hacky solutions meant to be temporary have a way of staying forever
Grand_Pop_7221@reddit
Nothing is as true in engineering as the "permanence of the temporary".
das_war_ein_Befehl@reddit
Probably because it works and making it âgoodâ requires changing a bunch of shit for literally no visible gain
vivri@reddit
AbstractConcurrentGeoLocationFactoryBuilderJO
IFYKYK
Teh_Original@reddit
JO = Java Object?
Bogus_dogus@reddit
Jorkin it
vivri@reddit
T'is the kingdom of nouns
subma-fuckin-rine@reddit
There's more nuance than that. I've seen crazy abstracted framework that could be replaced with a static utility call. Sometimes people just want to flex or try something out with no real need for it
East_Lettuce7143@reddit
Overengineering = Codebase I don't understand.
TwisterK@reddit
This is why I always over engineer but only to a certain point, if the code need more than 3 layer of abstraction, nope nada not gonna do it. Go back to drawing board and think thru what do u truly wanted
Sakura48@reddit
It's like coding the perfect solution for a feature that users never use.
nubbins4lyfe@reddit
Hey, unless I'm also responsible for choosing WHAT is being built, my only job is building it correctly.
Maktube@reddit
I think (in general, ymmv) it's part of our job to at least have some say in what's being built. A lot of the time that's either an engineering decision or it at least involves answering engineering questions, which is REALLY why you hire engineers, imo (as opposed people who can write code, but don't know how to do engineering, of which there are many -- I started out as one, coming from the computational physics world, and I can pretty safely say that it includes the entirety of academia).
nubbins4lyfe@reddit
I hear you. The plight of the professional who actually gives a shit, cares, and takes on full ownership of a product.
At the end of the day, they're selling stock price. Number go up.
It's why it sucks that this can be such an art form. Craft doesn't always equal business value.
RiPont@reddit
...and under-engineering can be solved with more engineering in incremental steps. Over-engineering requires massive refactoring.
Xanjis@reddit
I think that depends on your definition of those things.Â
It's easy to get from an excessively granular composition architecture to a less granular architecture. It's harder to get from an excessively monolithic composition architecture to a more granular one.
It's a nightmare to get from a giant inheritance blob to any sort of composition architecture.Â
Doing inheritance over composition is a pretty typical case of under-engineering.Â
LucaColonnello@reddit
Itâs not that linear in reality, it never is. It depends what you over or under engineer. You under engineer an entire architecture, you need to start from scratch and move so many pieces you end up rewriting the whole lot. You screw up a component of the architecture? If you didnât under engineer the architecture, you only rewrite that one thing.
GrumpsMcYankee@reddit
Anticipating requirements is literally part of our job
iMac_Hunt@reddit
Yeah a lot of businesses donât even understand their requirements. More than once Iâve built them something where the initial feedback has been âthis is too complicated, and they end up thanking me.
A classic example was that they wanted to be able to generate reports that look an exact way, with default text and fixed styling. I created a report builder that allowed them to customise styling and build templates with any text they want. Guess what? 3 months later the business needed a new type of report. They had a template builder rather than bugging me to code another report to their specification.
Thereâs a really delicate balance there, and you have to really to know your business, the domain they are in and of course your workload.
Big_Bed_7240@reddit
Textbook case of being outcome driven instead of process driven
AtWitsEnd1974@reddit
Yeah but the key point is requirements that actually end up materializing, versus making up edge cases for the sake of.
vzq@reddit
Exactly. And if you do it poorly, you do your job poorly.Â
We are in complete agreement.Â
GrumpsMcYankee@reddit
I framed it like a disagreement, my bad.
socialistpizzaparty@reddit
Yup. And this is where experience comes in. I know what my team can safely cut corners on, and what we canât. Also, anytime the client says something is âalways X and doesnât changeâ you make that a config somewhere because a few months later⌠itâll change :)
pydry@reddit
Not saying OP is one of the people who does that but he does sound exactly how the people who try to do that sound.
mwax321@reddit
Bravo. This answer is KISS approved.
Abadabadon@reddit
Lol I agree OP. I think alot of people are just making up excuses to be lazy, or are too scared to materialize a good design and face criticism.
keyboard_toucher@reddit
"We avoided overengineering" is an excuse not just for laziness but incompetence, poor planning, and any number of forms of doing a bad job.
SeriousMany2276@reddit
ok 1) shareholder value ewww, 2) no one is going to reward you for thinking tactically about your code, they just want it done and superficially functioning, good luck trying to convince them to take any extra time to actually get things in order. 3) do your best if thats what you want to do, but dont expect anything to come of it.
ichabooka@reddit
âOver engineeringâ is what people with no imagination and inability to create beyond what they learned in school say when confronted with anything that makes them uncomfortable. They will usually be your manager so tread lightly.
Leading_Yoghurt_5323@reddit
fully agree. âover-engineeringâ gets blamed way more often than âwe never actually designed this properly in the first placeâ
Rough_Priority_9294@reddit
Yeah typically people blindly saying things like KISS were pretty bad engineers.
Trawling_@reddit
Well duh, documentation is always useful. People must consider it part of the engineering process (it is) but are skipping out on it, to your point because of âover engineeringâ.
PageSuitable6036@reddit
Iâve yet to encounter an over engineered code base. I way more frequently encounter a neglected code base with very little care for future changes as long as it âworksâ, but maybe Iâm just not working at the right places
Teh_Original@reddit
Well feast your eyes on this bad boy: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition =p
PageSuitable6036@reddit
This still seems under engineered to me
Teh_Original@reddit
Shoot, you're right. They're missing the factories for the factories.
teucros_telamonid@reddit
Ugh, it is a joke, but. "Over engineering" in terms of time and effort spent could also lead to discovering very simple and elegant solution. So each time I see some monstrosity of shit tone of code with people piling up features on already shaky features... That is still an "under engineering" to me.
teerre@reddit
The issue is that "overengineered" for many people means "something I don't understand". I've seen considerably experienced developers thinking that using
std::rotate(and others named algorithms in std) is overengineering. This extends to almost anything. Often a system is called "overengineered" by people who don't understand the requirements. This is specially common for older systems where newer developers come in without contextThe basic requirement for being able to call something overengineered is being able to replicate it. You can't use it as a crutch for ignorance or lazyness. Unfortunately, that's the most common usage
teucros_telamonid@reddit
This is especially painful if you have a special domain knowledge. Something that you have seen 100x times across various code/libraries/projects in the industry, would appear as too complicated for anyone with only surface knowledge in the same direction.
stdmemswap@reddit
Easy to counter. Ask, "how and why is it overengineered?"
teerre@reddit
"Why complicate when you could use a for loop"?
In this situation the reason they think it's overengineered is because it's using some kind of construct or pattern that they aren't familiar with. It's very difficult to counter it because it's equivalent to giving a lesson in whatever we're talking about
stdmemswap@reddit
Your point is exactly my point. That counter question is often an escape from having to actually make the "overengineering" claim make sense. Call it out and don't let the burden of proof moce to you when the claim is theirs.
Like, "Wait, you haven't answered my question why would the approach an overengineering? How would for loop make more sense?"
Fatalist_m@reddit
Yeah, same thing with the "The Principle of Least Surprise". Sometimes, you find code "surprising" because you don't know things that you really should know.
Null_Pointer_23@reddit
And sometimes the newer devs are actually right, but mainly because they have the benefit of hindsight and have information that the original devs did not.
viditjn02@reddit
100% agree. worked on a codebase where everything was "kept simple" and after 2 years it was unmaintainable spaghetti. no abstractions, copy pasted logic everywhere, zero separation of concerns. under-engineering just doesn't have the same catchy warning label so nobody talks about it until the codebase is already a mess
Heavy-Report9931@reddit
ha! in my experience I've seen more over under engineering where literally everything is under engineered
failsafe-author@reddit
I donât believe over engineering is actually a thing. There are wrongly applied principles. But, thatâs really just bad code.
The thing about under engineering is that itâs often pragmatic, and itâs usually only experience that saves you from doing it. And these days, many people have suffered from code bases with misapplied principles, and so their experience tells them to be pragmatic. âWe donât need layers and abstractions- it just complicated thingsâ.
My experience tells me we DO need those layers, but there will always be pushback. And sometimes I get it wrong. Itâs hard to get it right, and there are always trade offs. The best thing is to be both intentional and consistent, and agree as a team.
Recently had a VERY experienced developer on my team tell me he thought the approach I was taking was âtoo muchâ. He made his case why, and I told him I understood his argument, he that my experience (which is considerable- I am a principle), it was the right call. He said that heâd said his piece, and he would do what I said. And he did. Every single PR is perfect code as I specified. Thatâs how you do it- and the code base is clean and readable. And if were to go into his already established repo, Iâd follow his conventions, even if I think more separation of concerns would be better.
contextfree@reddit
I just think if you're going to introduce a layer, you should be clear on exactly what is the value of the layer, what the "rules" of the layer are and how they realize that value, and then adhere consistently to them. Because if you're not actually getting anything from the layer it's better to not have it. I've seen people put layers in out of a vague sense that adding more layers makes it more proper enterprise engineering, then not actually adhere to the rules of the layers or even really define what they are, so they become these completely pointless indirections you have to wade through to find or change anything.
failsafe-author@reddit
See, you are already making the âpragmaticâ argument, and I get it.
I agree that being clear about the ârulesâ of the layer are important. âHow they realize valueâ is often much harder to convince Pepe of. Mostly layers add decoupling, which in and of itself can be hard to argue. When is it right to decouple? Can you go too far? There are usually arguments for and against, and itâs usually just hard enough to talk in concrete terms to convince someone who is doubtful (either direction).
But my experience is, at the minimum, if a web service doesnât have at least a layer of the API, a layer for the database, and a layer for domain logic, I ALWAYS end up regretting it and end up with more complex code than if I just started off with all three (even when that domain layer feels like a pass through for the first few iterations).
I think itâs valid to rely on experience in these cases i If you have to make arguments strong enough to convince doubters who just want to âcut the ceremonyâ, my experience is the default becomes no layers and difficult to untangle code. Iâd honestly rather have too many layers than not enough.
Street_Speed_8548@reddit
Your description of âunder engineeringâ just sounds like tech debt to me. And thatâs definitely discussed on the same level as over engineering.
Galenbo@reddit
A term only used by clueless sales/middlemanagement.
magichronx@reddit
I've been writing a bunch of Rust lately, and it's really pushed me toward making invalid state unrepresentable. Thinking/developing this way almost entirely removes the concept of "over" or "under" engineering; instead, it's either correct or it's not
CommercialFair405@reddit
Yep, making invalid state unrepresentable is one of the best things you can do to avoid unnecessary complexity.
im-a-guy-like-me@reddit
I fixed a broken db call that intermittently failed the testing suite with a CTE and the tech lead said it was over engineered. Because I used a CTE.
yxhuvud@reddit
Did the tech lead counter with a different piece of SQL that solved the problem in a simpler way?Â
im-a-guy-like-me@reddit
No. He rejected the PR on 4 different solutions, then told me exactly what to do, which was to introduce another non-deterministic result.
I'm a contractor. The tech leads solution to failing tests up until that point was a blank commit to re-run the 15 minute pipeline.
Healthy-Dress-7492@reddit
The problem with under engineering is that you are leaving the code devoid of guidance. You donât know who the next person to come along and mess with it will be, their talent level or time constraints. In reality they will spa some dog shit in the first place it fits without exploding and call it a day. ThĂŠ next person will do the same until you have a real steaming pile of shit that makes no sense to anyone.
What you want is to design with clear extension points, so the next person can easily see how to bolt their widget in.
gfody@reddit
a lot of stuff accused of being over or under engineered is actually just poorly engineered, lack of design is a rampant problem
SoInsightful@reddit
I disagree. What you describe as underengineering is just bad engineering.
Overengineering is when you unnecessarily do way more than needed to solve the task. You can't do less than needed to solve the task and then hand it off.
potatolicious@reddit
"Over" and "under" here are really misnomers. What you're seeing is when design patterns and abstractions become a poor fit for the actual problem being solved. Many of these problems occur because of "over-engineering".
And also honestly none of this sounds like actual problems. Your codebase evolves with your product and requirements. You will constantly find that some design pattern or abstraction that made perfect sense 2 years ago no longer makes sense now. The sneaky shortcuts through architectural boundaries, god classes, etc. are ways individual engineers try to work around this without tackling a broader refactor, and is a symptom and not a cause.
In any reasonably active codebase, at any moment in time something about your code isn't the right architecture. This is a forever process and is a natural outcome of reality changing over time. The important thing is to make sure you have the organizational support to keep refactoring as you need to.
Aware-Individual-827@reddit
My very impertinent comtribution to this discussion:
Design patterns are a poor fit since their creation.Â
Thank you for reading!
(I'm assuming a humorous stance on a serious take haha!)
recycled_ideas@reddit
Design patterns are a great fit FOR THE PROBLEM THEY WERE DESIGNED TO SOLVE.
The problem is that the problem they were designed to solve is giving developers a common language to talk about solutions, IE we used pattern X, but we changed it to do Y instead of Z because of A, B, and C.
What happened instead was that the industry and in particular the industry in the US went on an absolutely insane promotion obsessed track and people needed ways to justify those promotions and so patterns went from starting points for conversations to rigid guidelines and that's not remotely what they were intended or suitable for. And now we have developers with three years of experience calling themselves senior and implementating design patterns they don't understand in places and languages where they don't fit because "good" developers use design patterns.
ALAS_POOR_YORICK_LOL@reddit
Exactly. I worry about some of the guys in this thread saying you need to rewrite to get the right design.
Stellariser@reddit
Iâve seen vastly more under engineering that over engineering, and since youâre definitely not going to ever be allowed to go clean up the mess that was created by doing âjust enoughâ the last time itâs better to overdo it now than to spend months or years paying the cost of not doing it well enough.
anonperson2021@reddit
Depends. Startup needs, prototype needs and enterprise needs are different. Applying one mindset in another context usually results in over or under engineering.
maulowski@reddit
I actually donât think we over-engineer as much as we under-engineer. For example; your PM comes back with a feature. You build said feature and now you have to support it. Initially bugs are fixed right away but expanding on that feature set? Good luck. The code becomes an unreadable mess.
In my team, our Web API code was written by one guy and the whole thing became unreadable and difficult to work with after 8 months BEFORE release. We had functions that were 600 lines long and constructors with 10 or more interfaces being injected. Our UI code was so unreadable I actually ended up using LLMâs early on just to make sense of things.
Is the profit over-engineered? Hardly. What makes it under-engineered? Zero thought put into writing the code at first followed by a lack of follow through on refactor and clean up as well as a lack of solid regression tests
Ok-River6335@reddit
Pretty much this. A few years ago I joined a team that just got done revamping their application to version 2.0. I went though the code and it was so, so bad. Memory leaks everywhere, disabled all code quality checks. Developing for companies is so soul sucking and terrible I hope I never have to do it again
guitarist91@reddit
Bigger issue here is that your product and engineering teams failed to deliver a product after >8 months of development coupled with no clear technical direction
maulowski@reddit
We delivered the product on schedule, problem is that the second we turned it on we broke prod because we ended up DDoS'ing our own servers. :lol:
Working through ambiguity is part of our job requirement, it's just that we valued speed over everything else.
ClydePossumfoot@reddit
I think the middle ground, in my experience, is creating thin abstractions for concepts that can be âfilled inâ, expanded, and made more complex later.
Sometimes those components are dummy components that donât really do a whole lot. E.g. a rate limiter that just returns true. But when the concept of something is baked in from the start it makes things way easier to extend in the future when thereâs already a home for it to live.
Iâve rarely been mad about under-engineered abstractions.
Itâs been way more annoying to deal with abstractions that are over engineered from the start or abstractions that should have been there from the start and were not added because âYAGNIâ (yet).
Kind-Armadillo-2340@reddit
There's lots that goes into engineering code properly, but I think what you're describing is encapsulation. Encapsulation is almost always a good thing. You can also keep your code very simple and still encapsulate it properly.
When people say over engineering, they usually mean premature abstraction. Early encapsulation is nice because you don't need to introduce any abstraction, and it makes doing so easier at a later date.
ClydePossumfoot@reddit
Youâd be surprised at how many people conflate almost any encapsulation with premature abstraction. To be fair, code encapsulation is often representing an abstraction.
Drugbird@reddit
This seems like an example that's very easy to build in later. And also one that's probably better implemented later because you apparently don't know what and how you want to rate limit yet.
ClydePossumfoot@reddit
Itâs often not that easy to build in later. In general, the decisions made for the interface are more important than the specific implementation(s).. which can come later.
Very often the interface doesnât change. Takes a req, returns a boolean or raises a specific error (depending on your language/preferences).
Setting this up early sets the expectation up that requests can be filtered. How they get filtered is something that can easily evolve and change, but thereâs already a place for that evolution and the interface is thought out.
Of course this is just one (slightly poor example), but these kinds of things are the judgement that experienced engineers are paid for. Investments now, to reduce the cost later, without creating something with a costly maintenance burden.
Iâve been on-call at 3AM needing to mitigate an incident and have been extremely happy that simple but effective stubs/hooks like these were put into place ahead of time, in anticipation for the day that we needed them.
Too many folks see that as over engineering and that you only need to solve todayâs problem. That may be the case at a consultancy, or a new startup, or when adding a new small feature to an existing product.. but itâs really not over engineering when youâre creating platforms or infrastructure that are going to be there in 5-10 years and generally stand the test of time without becoming a big ball of mud.
Drugbird@reddit
That's not my experience, unfortunately.
I've seen many "stubs" where when the thing need to be implemented "for real", the stub interface was woefully inadequate and needed to be replaced entirely.
One other thing I often see if that "stubs" do not survive changes in code very well.
For instance, in the example of the rate limiter stub there a very real chance that it won't be applied everywhere it should. Non-functional code is non-functional after all, so defects likely won't show up in tests.
So you end up having to change the interface, change all the places the interface was used, and then also check the rest of the code to double check if it's was applied everywhere it should have been.
ClydePossumfoot@reddit
Youâre definitely right about a lot of that. One can do what Iâm suggesting above but still do it poorly or with the completely wrong abstraction. Minor changes to an abstraction are fine and expected.
This is why having this kind of experience on your team is extremely valuable, especially reviewing code on greenfield projects or projects that are âwideâ and may benefit from appropriate abstractions or where inappropriate ones may be costly.
WellHung67@reddit
Thatâs the risk. But itâs better to try to avoid that to the degree possible, rather than just assume itâll all be rewritten. In this case, you make a new rate limiter interface and you do your find and replace where itâs already used, then yes you have to find all the misses, but itâs still better than if it was never used at all in the first place. You kind of have at least some coverage in some places which makes the rewrite a bit less painful. I think the small effort to stub up front paid off in that case still.Â
TechnicallyCreative1@reddit
I was about to argue with you but this in incredibly well thought out. You're a better engineer than I am
WellHung67@reddit
Yes exactly. Make it work now as simple as possible, but donât paint yourself into a corner.
The rare times when the only way not to paint yourself into a corner is doing something marginally more complex, pay that cost then. Better to take a bit longer now and have flexibility than to ever paint yourself into a corner.
Itâs rare in my experience that you canât do something such that it can be improved later, while still following kiss and yagni. You donât actually implement the thing you ainât gonna need, but you make it easy as possible to implement later if you find out you doÂ
SpiritedEclair@reddit
Whenever we make a change, I ask, "does this prevent us from doing more in the future?" If so, I suggest we rethink it.
ElevatedAngling@reddit
I think this is an inexperienced dev pretending to be experienced posting on this sub
SkittlesAreYum@reddit
Nah. I have close to 20 years and maybe I've been unlucky but this has been my experience. I have never seen these insane factories everyone jokes about.Â
What I have seen are things like classes that should be interfaces but aren't so someone just keeps adding on new functions that only apply to one part of the product, when we could have injected the proper instance for that feature instead.
ElevatedAngling@reddit
Iâve known many devs that have been writing code for decades but I would still call inexperienced in many ways
BarfingOnMyFace@reddit
Maybe, maybe not. But the point is valid. People often under-engineer solutions. But I think OP is not touching on how the right engineering solution is truly a moment in time, not a singular answer. Otherwise weâd all wipe our hands after a job well done and never revisit a legacy project ever again.
Historical_Cook_1664@reddit
under-engineering is just the usual design compromises when there was never time alotted for documentation and things need to work not right, but *somehow*.
Kind-Armadillo-2340@reddit
In my experience it's more just not knowing better. I've lost track of the number of times a mid level or even senior engineer tagged me for review on a PR where the functions are in the wrong classes, there's a bunch of confusing mutable state, a bunch of unnecessarily optional parameters, confusing control flow, and poorly typed methods.
These are the people who are supposed to be reviewing other people's PRs to set these standards. There's usually just not enough people the are good at writing good software. Sometimes you have a handful of people who are able to get set these standards, but often times there's nobody who can.
hippydipster@reddit
Actual compromises would be an improvement over the norm. What's normal is just doing the next ticket and giving no fucks about such things as "design" or "architecture".
Historical_Cook_1664@reddit
at last my job we had a *great* architect and a ceo who *forbid* documentation as unnecessary expense. so any design decision that wasn't immediately obvious went ignored. we called it applied shamanism - important info was only proliferated orally.
apartment-seeker@reddit
Why would CEO be involved in such granular engineering practice decisions?
RiPont@reddit
Have you met CEOs? How many of them have a casual, sensible personality?
apartment-seeker@reddit
Even the most toxic or annoying ones I have met would not care about whether engineers write documentation lol wth
RiPont@reddit
Have you worked in startups with a first-time CEO/Founder/Engineer?
apartment-seeker@reddit
Yes, and with second-time guys who can be unintentionally abrasive and difficult to deal with sometimes, but no one who would have tried to be that in-the-weeds and micromanaging to try to promulgate and enforce such a ban.
NeonQuixote@reddit
Yea. The CEO tells us what to build, not how to build it.
AtomicScience@reddit (OP)
In my practice, it's quite often the laziness, not the lack of time, that leads to under-engineering. And from there, even if there is no pressure from management, it snowballs into a good ol' Big Ball Of Mud that no one will dare to clean up
Crafty_Independence@reddit
How are you an experienced engineer with this opinion? It's like you've never worked in a mid-sized or larger company.
At a certain point in company sizes, the development team tends to lose a lot of control around priorities and timelines, and you spend a lot of effort hammering out compromises left and right because there isn't enough time to build everything the business wants when they want it
Refmak@reddit
This is what happens when a lead engineer drops the ball on the âleadingâ part of the job titleâŚ
If the team is not able to make it in time, then itâs up to the lead to hold stakeholders responsible for the compromise. âWe canât make it for X because John Doe wants us to work on Y. If you want both we need Z engineers/consultants/moneyâ.
If the lead engineer starts encouraging the team to cut vital engineering practices to âmake itâ, then the game is officially lost because youâre sacrificing the future time spent on maintenance (future time you will never have)âŚ
Crafty_Independence@reddit
You are assuming the lead engineer gets to make that decision. There are many organizations where those decisions are made above their level and they have to compensate best they can.
In many organizations, the engineers *report to* the stakeholders.
Refmak@reddit
Yes, engineers are often a cost center everyone gets that. If you only report to stakeholders and canât manage them, then youâre not leading but instead just an overpaid sprint planner.
I swear some leads antagonise stakeholders as enemies despite working at the same company lol
Crafty_Independence@reddit
No doubt. I have the impression that FAANG actually helped foster this mentality by having engineering be completely separate from a lot of the actual hands-on business, so engineering teams sometimes see themselves as not belonging to the organization.
Refmak@reddit
Yeah thatâs plausible, but I think also because asks can feel unjust despite their value.
Sometimes leading is proving to stakeholders why their ask isnât feasible, instead of being a yes-man and shoving it to refinement. Many leads miss that step because it has a negative connotation to push back.
Nevertheless if the value is high enough then business usually also wants to support it with more funds - but itâs on the lead to prove that they need it.
AtomicScience@reddit (OP)
I did work in quite a few places, small and large, but I'll admit I never was on an overwhelmed team with all deadlines burning, so I may be naturally biased towards perfectionism, I'll admit that
Crafty_Independence@reddit
Well to be quite frank your experience is quite anomalous for our industry
AtomicScience@reddit (OP)
Guess I just got lucky... Always had decent managers, and good processes were in place most of the time. Such a shame most folks cant relate
MyriaCore@reddit
Would kill for your environment ngl
twowordsfournumbers@reddit
Welcome to the sub, brother.
A dev who has never grown past junior after 5+ years is still an "experienced" dev.
Jaegermeiste@reddit
I wouldn't say laziness per se, but rather often a naive approach by someone with a lack of architectural perspective.
I'd say being under informed about the trajectory of the business also contributes - it's easy to paint yourself into a corner if you don't know what those plans are. Take, for example, localization - if you know that expansion into the ASEAN market is targeted for 2027, you might give serious consideration to using a proper i18n framework upfront instead of hardcoding English strings everywhere.
Avoiding over-engineering is not simply saying YAGNI to everything, it's making a decision to implement/reject some feature based on an informed cost-benefit analysis that includes the application/system architecture, the end user use cases, the ecosystem, the environment, the lifestyle, the reasonably expected future budget/resourcing, and the business strategy for the product. Sprinkled with a dusting of clairvoyance.
AtWitsEnd1974@reddit
Itâs the product owners responsibility to forecast the business.
The PO should accurately forecast the trajectory of each story with at least a 10 year outlook, such that all edge cases over the 10 year period are initially accounted for in the design.
afwaller@reddit
most products don't even last 10 years.
twowordsfournumbers@reddit
It just sounds like you have a shit code base, and the culture is startup-esque ship philo. Most of the things you've mentioned is culture specific, and a good senior wouldn't hand let it get that far.
Under engineering is more stuff like, 5000 lines of code in one file, no discernible architecture, hard coded values, 0 edge case / robust checks, no testing, no planning, etc.
Under/over typically refers to the amount of thought or planning. 100% edge case coverage is typically over engineered and 0% is under engineering.
stdmemswap@reddit
There are many conflated definitons of overengineering in this thread, either:
The cartesian decomposition dillema is always about "what if we need it in the future?" It is partially solved problems tbh. There are techniques and tools for making things extensible, like versioning, backward/forward compatibility, etc. The ultimate technique is dependency injection in a broad sense, where you inject your problem space into a static solution space; example, DB engines, Game Engines, portable computations (e.g. wasm, VMs), Generics, etc.
Mechanisms at the wrong layer of abstraction is a matter of thinking relationship of lifetime between rules and infrastructure: "should these rules be dynamic or static relative to this layer?"
Last, bad taste / good taste is about experience and linguistic/design talent
ISieferVII@reddit
That all sounds like a symptom of Agile.
BrofessorOfLogic@reddit
Fully appreciate what you are saying, and I think it comes from the right place, but I disagree with almost everything here.
Both over-engineering and under-engineering are bad things, it's in their names. But I don't see them as opposites ends of the same spectrum. In my experience, the underlying reasons for why they occur are fairly different. And you can't really measure these things anyway.
I don't think we mostly talk about over-engineering. I think there is a ton of material on architectural patterns and design patterns, and on how to get things just right.
I also don't agree with the sentiment that you should care more or less about business value (or shareholder revenue as you call it). If you work in a business, then everything you do should be related to it.
It's a mistake to think that good design and architecture is at odds with good business. Good software is good business.
Would be better to leave the broken windows theory out of it. This theory talks about crime in neighborhoods, not quality in software. Also it's highly debatable whether it's accurate in the first place.
MocknozzieRiver@reddit
I definitely agree. I went from an over-engineered codebase and to an under-engineered codebase.
Yeah, the over-engineered one could be hard to understand at times. But once you got it, making changes and additions was a breeze, or you'd discover that someone already built the feature you need because they predicted it would be needed. And the process of figuring out the over-engineered codebase taught you a ton of new things that were useful later.
Now I'm working in an under-engineered one, and it's mind melting. Incredibly difficult to safely make changes, incredibly difficult to understand, and sometimes leaving sensible language features on the table to avoid "complexity" and "over-engineering"...
VizualAbstract4@reddit
Our backend does. I feel like my company/boss would call me out for over-engineering (what they call over-engineering is really just called planning) if it werenât for him and the backend team being too busy trying to implement features and completely re-engineer ones that ended up being insufficient.
I donât understand how they think itâs more effective to skip a few hours of thinking through something and not see the massive time sink it is.
The usual argument is âwe wonât know if what we built is right until we put it in peopleâs handsâ
My response really should be âif you canât tell when something obvious is wrong or missing, youâre not thinking about the users anywayâ
TheBear8878@reddit
Shut the fuck up chatpt
OddEstimate1627@reddit
Reading through the comments, I really appreciate working mostly by myself, on an appropriately engineered codebase, and with very few deadlines or time constraints.
I can't imagine working in a huge corporation with multiple layers of team leads and architects with different opinions. How does anyone ever get anything done?
IMP4283@reddit
Meh. Personally Iâm a fan of developing the simplest solution possible to get the job done. Complexity is only needed when/if itâs add value or solves a real problem.
liquidpele@reddit
Why not both? Â At the same time! Â
bwainfweeze@reddit
No the most frustrating thing about overengineering is that it means people had too much free time, which makes the underengineering in the rest of the code feel like theft of attention by the other bits.
kriminellart@reddit
Jokes on you, mine suffers from both over- and under-engineering. The best part though is that the trivial stupid stuff is over-engineered and the hard stuff is under-engineered.
It's production code at its absolute finest.
RageFucker_@reddit
Totally agree. I also feel like people throw around the term "over-engineered" any time they have to look at complex code.
Recent_Science4709@reddit
IMO shit take. The under-engineering you speak of is from novices who don't know what they're doing most of the time, lack education and formal training. They don't know any better.
Over-engineering is usually by people who should know better. This post sounds like cope.
Unlucky-Ice6810@reddit
The worst is people under-engineer important bits (fundamental constraints, CAP theorem, whether the chosen framework is even vetted to work WITH the workload in mind) and over-engineer fluff ďźDRYing every little thing).
I'll fight tooth and nail on the former, and is fairly lax on the later.
After-Fig-9457@reddit
yeah,,, honestly, I've rarely seen true "over-engineering" in the wild.. under-engineering is way more common it's always those small " we'll fix it later" decisions that pile up until everything feels fragile.
death by a thousand band aids is exactly it and by the time you notice, no one wants to touch anything anymore.
lookmeat@reddit
All over-engineered code is paradoxically also under-engineered, and is therefore, worse.
Over-engineered software is software that spends a lot of effort, complexity and weight on something that is not useful. This means it's not spending enough energy or effort on the things that do matter, and it struggles at that as well. To fix over-engineered code first you need to undo the over-engineering, and only then can you understand how it's under-engineered.
Moreover under-engineered or over-engineered is the natural state of software. We are trying to solve very weird problems, that then keep changing the rules as they go, and they layer upon each other in ways that don't quite fit. As such we always have an ill-fitting solution to a problem we don't quite understand that much. We keep iterating and improving on it, asymptotically, but never quite there. So we don't aim to "engineer" it correctly, we aim to make the code resilient, and that requires most times to risk under-engineering rather than the opposite, and other times it is best to over-engineer (e.g. use a battle-tested powerful library rather than rolling out a mediocre solution yourself). Knowing when to use which.. that's the intuition you get as a developer, with practice and mistakes and iteration.
exomyth@reddit
Over engineering is the enemy of progress, but poorly thought out code is going to bite you.
I find that the sweetspot is a generalized solution for the problem you are trying to solve, but nothing more. Implementation time is about the same, but it is generally less naĂŻve
_hephaestus@reddit
Probably because survivor's bias is a huge part of this. A decent chunk of the time something is overengineered the "over" comes into play because you put a lot of effort into something that's not actually being used, the rest of the time it's because someone put a lot of effort optimizing a particular approach to the problem that's too narrow and interferes with future development.
The survivor's bias is also relevant because if we have sufficient resources then of course, load balancer in front of anything. If shit's on fire, you should be paying down tech debt, but you also have to be strategic about how you do it and approach things from "is this the biggest fish to fry". Even if shit's not on fire if you can't tie engineering investment to some strongly desired functionality (even if its functionality is improved engineering QoL), then you're optimizing poorly. If you're optimizing correctly, then it's not overengineering, it's just engineering.
Final_Potato5542@reddit
"Maybe I'm just too young and read too many smart books, and care a tad too much about shareholders' quarterly revenue, but isn't that common sense "...
yeah, okay bro lol
Techno_Peasant@reddit
Donât forget the ever popular, over complicated due to feature bloat issues that seem to lurk within the repos of every company.
a_library_socialist@reddit
Yeah, the benefit of experience is I can whip out a properly engineered solution that has OOP seams and all the other parts of "over engineering" as quick as writing slop. It's just by the numbers at this point.
NoobPwnr@reddit
Isn't that like calling water wet? It's the point.
Isofruit@reddit
What you're describing is just somebody not refactoring the codebase as requirements change? Why do we need a new word for this? You can either write highly abstract and flexible code that tries to anticipate all sorts of requirements that do not exist at the time, or you solve the requirements you have right now and as they change, you refactor the codebase accordingly.
If you overdo the former, you burn time twice, both in the initial implementation and when people have to take forever to understand the abstract setup so they can apply changes as needed.
If you do not do the latter you pay for it with code that is more likely to be buggy and people having to take forever to understand the messy logic setup so they can apply changes as needed.
mushgev@reddit
The AI-coding era makes this worse and it's not discussed enough.
Tactical programming has always been the root cause -- small, myopic changes without strategic thinking. The problem is that AI coding makes tactical programming the default. The feedback loop is: write a prompt, get working code, ship it. At that pace you get 10x more "it works" decisions per week without 10x more "does this respect the architecture" decisions.
God classes grow faster. Layer violations accumulate faster. The implicit coupling that takes a team six months to accrete now takes six weeks. But code review hasn't gotten 10x faster, architecture documentation hasn't gotten 10x more thorough, and nobody is running 10x more structural audits.
The under-engineering problem isn't new but AI coding has compressed the timeline. Codebases that used to take three years to become genuinely hard to reason about now get there in a shorter window. The people who figured out how to maintain architectural discipline at human coding speed are going to find those same habits don't scale by default.
editor_of_the_beast@reddit
This is 100% accurate. Most teams throw the baby out with the bath water.
dethstrobe@reddit
I completely disagree.
Refactor early and refactor often. Have a good and robust test suite to make refactoring safe.
Predicting the future is hard. So don't. Built for what you need when you need it. Early abstractions are harder to work around then keeping things YAGNI. And built things to be modular so you can discard it when it is no longer needed or easier to refactor when you need it.
coderemover@reddit
I totally agree that most systems suffer from under engineering. There is this vicious cycle: 1. a release deadline comes close, 2. the product undergoes full release testing 3. bugs are discovered, 4. there is not much time to fix them, letâs fix them by gluing some duct tape, ie adding a few more ifs here and there 5. the tests finally pass, ship it 6. release done, letâs cleanup the codeâŚ. ânooo! What are you doing?! Donât touch it if it works!â
Soasafrode@reddit
Over engineered is a term used by non-engineers. A real engineer, if they heard that term for the first time, would think it meant too pragmatically simplified.
bigfatcow@reddit
Jokes on your bud my code is both over engineered in some parts and under engineered in others. Lifeâs about balanceÂ
wrex1816@reddit
How about just concerning yourself with the problem at hand and applying the best practices and principals that you learned in your studies?
At the same time, stop trying to fit every single problem into the same box and trying to scold peo6online for not doing everything the way you tell them.
Not everything has to be a click bait social media headline.
Teh_Original@reddit
Software is a data transformation problem. It takes inputs and transforms them to outputs. Your application is defined by the data it processes and the transformations required.
Professional_Fall774@reddit
For me, the the meaning of over-engineering mean too complex and the opposite under-engineering too simple, I would go with under-engineering any day. A new requirement that was not foreseen can make a over-engineered solution even more complex where as a too simple solution is more easy to bend to cover new cases.
Your interpretation of under-engineering is relatively easily solved with documentation, architecture tests, linters, code-reviews, etc.
AndyKJMehta@reddit
There is no such thing as âunder-engineeringâ. There is only PMF and cash flow. Everything else is dev ego.
Famous-Test-4795@reddit
This entire field is trying to fit a box around constantly moving targets.
uniquesnowflake8@reddit
Yeah the important part is code thatâs easy to understand and change without unintended consequences
Expert-Reaction-7472@reddit
some developers like to gold plate things, others like to get stuff done.
I worked at a start up with a CTO who was obsessed with obscure open source distributed systems projects - it was cute but it wasn't shareholder value.
Limp_Technology2497@reddit
These are not mutually exclusive.
I for one will often plug in a strategy pattern or a code-based rules engine if I think a spot is going to be a path for tenant based customization in the future.
Then from there, we can decide if we need externalized configuration.
Expert-Reaction-7472@reddit
ah found the pattern obsessed gold plater.
ClydePossumfoot@reddit
Thatâs not what the person youâre replying to is suggesting at all. Itâs not a premature optimization, itâs hedging a bet on something being likely.
Those judgement calls, which experienced engineers should be making, are investments in the future. Doing this kind of thing early often isnât a âpremature optimizationâ, itâs the difference between a config change to roll something out/maybe half a days work and the time spent engineering the solution months/years after the initial implementation and attempting to wire that through the now expanded codebase.
Itâs this kind of thing that drives real impact and value when youâre able to roll something out that otherwise would have been deprioritized indefinitely because the cost to do it in the future is way higher than the cost to do it at the start + the small maintenance overhead.
Now you shouldnât do this all the time of course. But these bets are extremely valuable over time.
Expert-Reaction-7472@reddit
a strategy pattern with one strategy is just a waste of space
couchjitsu@reddit
Shows what you know.
Mine suffers from both simultaneously
codescapes@reddit
What you're describing is like a "greedy algorithm" approach to software development. Always make what seems like the quickest solution to solve your problem right now.
I'm trying to fight this mentality with UI design in my current role. I absolutely hate it, just constantly adding extra dropdowns or buttons with no consideration for overall product cohesion, considerate design etc. Then we're left being told by customers the product feels bad and it's like yeah, it does.
And the only way you can get around that at both the backend and frontend level is with leadership that values doing a good job. The problem is that greedy algorithm thinking is usually good enough for most things even though it sucks to put up with.
need-not-worry@reddit
I find most of your complaints - shortcut through architecture boundary, God class, implicit coupling, can also be explained by over engineering (and tight dealine, of course)
All can be solved properly, but uf the codebase is over engineered, the proper way is too hard and people gets lazy
TastyToad@reddit
Maybe I misunderstanding something but the term you're looking for is, most likely, "technical debt". And we talk about it all the time.
If you want to be pedantic you could probably differentiate between "didn't know better" and "knew better but f....d up anyway due to laziness / deadline pressure". First one could be your "under engineering" then.
sweetno@reddit
One does not preclude the other.
No_Armadillo_6856@reddit
Under-engineering is not following the best practices of the language/framework, not using frameworks correctly, cutting corners and doing quick temporary (permanent) solutions and not using consistent logic.
Over-engineering is trying to build concrete structures before there is any understanding of what the requirements are going to be like.
boring_pants@reddit
That's not my understanding of the term at all.
What you're describing is "not giving a shit about your code". That is different from under-engineering.
Under-engineering is designing a solution based on an assumption that the problem was simpler than it actually was. That doesn't mean you wrote bad or sloppy code, it just means you didn't anticipate every nuance of the problem and its "proper" solution.
GrumpsMcYankee@reddit
It feels like the underlying maxim is change as little as necessary to get the job done, and following that, you build as little as necessary (but no less) to keep your footprint small. Every extra component, facet to your code, it adds weight and risk.
But flip side, I think it's a guessing game which feature needs room to expand, and structure to follow down the road. And I absolutely err on too much when I have the time and feel there's cause. And maybe the under-engineered stuff is laziness, but it's hard to say. You're always anticipating the future but can't determine the path it'll follow.
originalchronoguy@reddit
In my experience, it is often pure laziness. If it is not written in the user requirements, they wont do it and deal with it 6 months later when it comes up. Like no one thinks about future proofing or extensibility.
Example I have to fight for. A grid. Simple table with text. I argue to have the cell contain an object vs a string. Takes an extra 30 seconds to define that. An object can handle future scenarios like image vs plain text. Or embedded data-types like another grid inside a grid. It is a 15 second variable assignment. We spent more time arguing about keeping it a simple string. Because it was not written in the user story.
ContemplativeLemur@reddit
I loved to see a good engineered code that could adapt to new things and accommodate new features easily.
Thought the years I begin to prefer 'bad' code that is hard to increment, but easy to test, debug (as there are few abstractions is trivial to understand) and mainly easy to throw away.
All code is considered 'legacy' and 'monolith' after some years.
Writing code is the easy part. Throwing away the old code and re-implement when new features arrive is easier than to create a god code from the start. A good testing framework is more important than the code itself. Consumers don't care how dirty the code is.
I lost count how many times a simple feature turns into an AbstractConfigurableSuperScalable feature, that takes much longer to implement, test and debug. Just for years later it still do not need any extra configuration or support any different scenario after years...
lokaaarrr@reddit
Code will have a short life, APIs need to endure, with sensible updates in some cases.
roger_ducky@reddit
Itâs a good pushback. As long as the person can explain exactly why the complexity exists without making it a âjust in case itâs neededâ argument, then thatâs fine.
Itâs why I typically ask why it exists rather than assuming itâs over engineering.
Sometimes Iâll ask âwhy canât we do Yâ instead, but will accept it if it could be justified.
Limp_Technology2497@reddit
In the current era of agile development and massive development teams, I feel like weâve probably all just converged on building Winchester mystery houses.
Acrobatic-Ice-5877@reddit
IMO it depends on the engineering maturity of the person calling the shots. For example, I love DDD and know itâs not everyoneâs cup of tea but once you join the cult, it becomes difficult to leave.Â
People who arenât drinking the koolaid see it as over engineering but I see it as freedom. DDD forces business rules to get formalized and you move from CRUD style implementations where tribal knowledge is king, to having clear explicit rules that can allow anyone to jump in and make improvements or fix mistakes.
Sometimes you just canât get people to see things your way and thatâs the hardest part about working in any field where there is a degree of autonomy to execute. Youâre always going to be competing and working towards influencing people if you care about doing things the âright wayâ. I think as you get older, you learn what battles are worth fighting and which ones donât matter.
lolCLEMPSON@reddit
Most complaints of overengineering is really just shitty engineering and over-complexity
robhanz@reddit
The issue is usually people assuming that theyâre going to get it right the first time.
âOver-engineeringâ is a matter of trying to get it right up front, only to have requirements change. And then not updating to match the reality.
âUnder-engineeringâ is the same thing, but starting with less structure. Itâs moderately better because at least you get something done before your codebase calcifies.
MonochromeDinosaur@reddit
Over-engineering to me is the opposite of YAGNI and KISS.
You choose an adequate level and type of abstraction and implement your use case narrowly.
Anything extra is over-engineering unless you KNOW youâre going to need the extra.
yxhuvud@reddit
Instead? Most code bases suffer from both at once.
DoJebait02@reddit
Sometimes speed is the most priority factor that forces you to choose where can be cut off.
Then itâs where experienced planners come to shine with a careful plan between human resources, requirements, demands, time and refactoring.
gfivksiausuwjtjtnv@reddit
Bad code != under engineering
âShortcuts through architectural boundariesâ if youâve seen some of the stuff Iâve written thatâs deliberately under-engineered youâd have an aneurysm. Yet things are exactly where youâd expect and the code is easy to delete instead of easy to extend.
mrmcgibby@reddit
I think you misunderstand what people are talking about when they talk about over and under engineering. Over engineering doesn't mean someone spent too much of time creating a well crafted system. It means they added more structure than necessary to solve the problem. And what you call under engineering is just bad engineering. And we rail against that just as much as anything else.
PM_ME_YOUR_SUBARU@reddit
Overengineering doesn't exist. Engineering is hitting a local maxima - a miss in either direction is under-engineering.
AtomicScience@reddit (OP)
Of course, engineering is a multidimensional problem - and there will be some sweetspot, and any other solutions outside of it will be 'mis-engineering', you are right here
I tried to focus on one dimension, and along the axis of 'resouces spent on a problem', we could totally identify 'over-engineering' and 'under-engineering' regions, dont you think?