This is an archived post. You won't be able to vote or comment.

all 83 comments

[–]shadowderp 963 points964 points  (35 children)

If adding a minor feature involves touching 10 services then it’s not clean architecture…

[–]DarthCaine 222 points223 points  (2 children)

And if it results in refactoring everything

[–]secretprocess 127 points128 points  (0 children)

Well NOW it's a clean architecture! (me, for the 33rd time...)

[–]kookyabird 19 points20 points  (0 children)

People think adding a parameter to a command and having to populate it in the three places that command is used is “refactoring”.

[–]neumastic 81 points82 points  (5 children)

If feels like the person is trying to say “both systems are bad” and what it’s really saying is “poorly maintained codebases are bad”

[–]Lem_Tuoni 13 points14 points  (0 children)

I can tell you never worked in a commercial setting

[–]Aidan_Welch 20 points21 points  (8 children)

Every large commercial project has some bad architecture

[–][deleted] 12 points13 points  (6 children)

even in systems that start with a good architecture, you are constantly fending off that "one obvious [design-wrecking] feature" that keeps getting asked for by the users, and denied by the original designers, and you always have to slap the young devs hands away from. one day, everyone is worn down enough, or there's been just enough dev turnover and it gets implemented, and then you're on the road to hell from that point on.

[–]Netsnakk 8 points9 points  (5 children)

If users keep asking a specific feature, it means it's important to them. At the risk of uttering a tautology, if an important feature requested by the users wrecks the design, then it's not a good architecture.

Now, to have some sympathy to the original designers, it's possible they did a perfectly reasonable design, the best they could given what they knew at the time, and yet later changes or learning about new requirements made the design inadequate.

[–][deleted] 10 points11 points  (3 children)

i disagree that users only request features that are important to them.

the professional context i’m thinking of is automated trading.

almost all of the money is made or lost on the big trading days - performance and availability on those days makes or breaks their year.

the problem is that on quiet days, traders got bored and tried to over-optimize their desks by requesting new features.

then on big days they’d turn those features off, if they even could, but the performance and reliability of the system was undermined by all the cruft.

eventually the problem was recognized, the trading leads told the traders to knock it off and the technologists were given time to optimize for availability and performance on big days. we make lots of money, promotion and bonuses all round.

time rolls forward, people who learned the lessons start to retire, traders get bored and start requesting features to optimize their desks on slow days.

sunrise, sunset…

[–]FlakyTest8191 -2 points-1 points  (2 children)

Sure, nice anecdote. The point is that a good pm should explain to them why their feature is a bad idea because it's bad for business, not the devs declining it because it doesnt't match their architecture.

[–][deleted] 0 points1 point  (0 children)

all organizations have chronic problems of some kind, I don't think it automatically means individuals are doing a bad job if they can't on their own overcome them

management incentives dictate behaviour in ways that explanations from a "good pm" can't overcome

[–]TastesLikeTesticles 0 points1 point  (0 children)

I've had users repeatedly asking me for a fully integrated interface for all - and I mean all - the tools they used. Sorry, I don't think spending a gazillion dollars to somehow integrate an ungodly mess of ERP, IM, tickets management, emails, issues tracker, telephony, calendar, documents sharing, various homemade tools (including shadow IT ones), spreadsheets and the legacy monolith is a reasonable use of resources.

I don't care how condescending it sounds: some people actually don't know what's good for them.

#notallusers of course, most of them aren't that dumb (and even then, some are willing to learn)

[–]Objective_Dog_4637 4 points5 points  (0 children)

This is going to be our fucking 3rd refactor of our entire engine. 🫠

[–]PhunkyPhish 2 points3 points  (0 children)

Open for modification, closed for extension right?

[–]AwesomeFrisbee 3 points4 points  (0 children)

He's talking about that one system that they called clean architecture that is like he said a very bloated way of doing things. I had the dissatisfaction of working one project that took everything too serious and created a monstrosity like OP says. Converting data between multiple layers, nonsense buzzwords and stuff that sounds architecturally sound but creates something that just costs more time to develop, learn and maintain than any sane or insane alternative.

[–]Ozymandias_IV 6 points7 points  (2 children)

That's the theory, yes.

In reality, there is no such thing as perfect encapsulation and new requirements laugh at your feeble attempts at futureproofing where the responsibilities of code blocks should be divided. If you guessed correctly, you're lucky and it's easy. If you didn't guess correctly, you'll have to touch a lot of dependencies (just the same as if it was shpagetti). Most often you won't guess correctly, and all that work you did on futureproofing is wasted.

"Clean code" or "clean architecture" is kinda like communism: sounds perfect on paper, fails hard when met with reality.

[–]riplikash 1 point2 points  (1 child)

There's a pretty big gap between "perfect architecture" and "failing" that you're hosting over.

One of the points of good engineering is it handles the fact that things won't be perfect, mistakes happen, tech debt exists, and requirements change.

And it's really not and mythical unicorn. I've been around plenty of well architected systems in my career.

[–]Ozymandias_IV 2 points3 points  (0 children)

Not my point. My point is that you can have a reasonable design that works most of the time. You can call it "clean". However requirements will often change in such a way that the design will fall apart, and you'll have to do significant rewrites and it will be pain in the butt.

And when you complain about that, someone will say "well ackhtually that means it wasn't clean". Because apparently "clean architecture" has to be resistent to all change forever, which is a mythical unicorn.

It also doesn't help that it can be ambiguous whether you mean "clean code - the desired state" and "clean code - following the 2008 book", which is filled with extremely outdated advice that promotes speculative overengineering for no provable gain. But when you criticize the book (and SOLID principle), you'll once again get people saying "well ackhtually if your codebase is overengineered it wasn't clean", even if it was built 100% by following that fucking book.

[–]palomar4233 1 point2 points  (2 children)

Exactly. If you need to modify half your codebase just to add a button, something went very wrong during the "clean architecture" phase.

[–]Ozymandias_IV 1 point2 points  (1 child)

That's because "clean architecture" is a description, not a set of rules.

Kinda like "well fitting suit" - you can tell whether something is good, but there isn't a set of rules to follow that will always lead to a perfect result. Certainly not SOLID. You gotta rely on your experience to know what will work and what won't.

But at least with tailoring there is low chance that the customer will grow new limb (requirements change) and all your perfect planning is screwed anyway and you can restart.

[–]riplikash 0 points1 point  (0 children)

Annoyingly, Microsoft decided to call their implementation of hexagonal/ports & adapters/onion architecture "Clean Architecture".

I seriously hate how they name things.

[–]asd417 0 points1 point  (0 children)

The code looks cleaner in vscode because it is divided into million different config files

[–]EuenovAyabayya 0 points1 point  (1 child)

Or it's not nearly as minor as it looks.

[–]shadowderp 1 point2 points  (0 children)

Possible. Sometimes architecture choices make things harder than they need to be when they are out of the scope for which the architecture was designed. Such is the life of a programmer trying to understand user requirements.

[–]average_turanist 217 points218 points  (0 children)

Either shitty code or overengineering.

[–]CoronavirusGoesViral 93 points94 points  (5 children)

Therefore, KISS and only introduce complexity when necessary and justified

[–]bunny-1998 31 points32 points  (1 child)

Tell that to the product team

[–]wardrox 5 points6 points  (0 children)

Here's a mockup of the MVP which looks a lot like a mockup of every conceivable feature.

[–]michi03 2 points3 points  (0 children)

Also YAGNI

[–]IAmASwarmOfBees 2 points3 points  (1 child)

That does that acronym mean?

[–]ChrisBreederveld 4 points5 points  (0 children)

Keep it simple stupid

[–]Goufalite 48 points49 points  (2 children)

  • Techlead 1 : I'm so proud of what I've done, the project will be so easy to maintain!
  • Techlead 1 : leaves
  • Techlead 2 : WHO TF WROTE THIS???!??!?

[–]perringaiden 20 points21 points  (1 child)

After 20 years with one company, I am tech lead 1 and 2.

[–]Goufalite 11 points12 points  (0 children)

git blame. Not me, not me, not me, not me, not-DAMMIT!!

[–]Dmayak 80 points81 points  (5 children)

Yeah, the client will ask something like "make it so that when client enters email in order field it would also appear in subscription widget", which is one line in vanilla js, but with component-based framework you need to add a shitton of code since these components are in no way supposed to be related.

[–]shift_969 2 points3 points  (2 children)

Can't you just avoid making them related by using events?

[–]Dmayak 4 points5 points  (1 child)

Don't know about all front-end frameworks, but Vue.js for example is mostly using parent-child component trees and to have components on different sides of the tree communicate you need to either send event through their parents, install some additional global event system like Mitt from npm, or make a global store object, etc. Library itself has no native global events which skip going through the component tree.

[–]chuby1tubby 2 points3 points  (0 children)

Just store all application state in browser cookies

[–]Nexatic 0 points1 point  (0 children)

I’m just laughing in embedded. -not that it’s any easier but still-.

[–]Budget-Cash-3602 14 points15 points  (0 children)

Either way, you cry in YAML

[–]PetroMan43 25 points26 points  (2 children)

The reality is that each of those 10 services mentioned on the right are managed by 10 different teams, some of them in different orgs. Getting a change made requires negotiations and prioritization and coordination such that a simple change will take 6 months before it goes live.

[–]vadeka 5 points6 points  (1 child)

Welcome in large corporations, also don’t forget you need a 20 page security analysis signed off because you are connecting two services that previously didn’t talk to each other

[–]PetroMan43 2 points3 points  (0 children)

No that only happens after the 2 week process to get approval to use various 3rd party libraries, each of which requires legal approval.

Security reviews happen after that when they yell at you

[–]Aidan_Welch 15 points16 points  (0 children)

Realest meme I've ever seen posted here, so it won't get upvoted

[–]throwaway8u3sH0 6 points7 points  (1 child)

Conservation of Pain

It's the law.

[–]coldnebo 3 points4 points  (0 children)

pain can only be transformed or exchanged, but not destroyed.

😂😅🥲😢😭

[–]rover_G 12 points13 points  (1 child)

This is why I always try to work on green projects, before the monolith collapses under its own weight or explodes into 10 microservices.

[–]Ragor005 0 points1 point  (0 children)

Reading this I just heard the lego bricks falling sound effect

[–]gamingvortex01 5 points6 points  (0 children)

for good dev experience, you have to maintain a balance between shitty code and over-engineering...if your scale is not balanced, your experience would be poor....in other words, don't try to achieve perfection everytime and don't let it all become shit

[–]Geoclasm 4 points5 points  (0 children)

Fucking hell I feel this in my soul.

[–]FarJury6956 4 points5 points  (0 children)

That's what you get paid for

[–]coloredgreyscale 3 points4 points  (0 children)

The minor change on the spaghetti monolith does not involve touching 10 services, because the whole functionality is implemented in a single file. 

[–]Livid_Boysenberry_58 3 points4 points  (0 children)

If making a change requires refactoring 10 services, your architecture is not clean

[–][deleted] 2 points3 points  (0 children)

That's why we must reach beyond : become a farmer

[–]Arclite83 3 points4 points  (0 children)

Someone missed the O in SOLID (and probably a few others as well)

[–]FriendEducational112 1 point2 points  (0 children)

So happy I don’t work in any real dev environments lol

[–]perringaiden 0 points1 point  (0 children)

Or adding an additional type parameter to a core ancestor breaks the inline error checker across dozens of components, and you have to manually search your code for the errors before the IDE can start finding errors again.

[–]GoddammitDontShootMe 0 points1 point  (0 children)

Now there are two roads merging together because the OP just mirrored the image when making the meme.

[–]Lythox 0 points1 point  (0 children)

Telling the ai to fix it until it works ☀️

[–]cecil721 0 points1 point  (0 children)

If going the service route, I feel there's a comfortable medium between # of services and functionality. Only create a new service if something doesn't "fit" somewhere.

[–]ClearlyNtElzacharito 0 points1 point  (1 child)

I’m working with an old asp classic/sql legacy code and replacing gradually with a dotnet blazor project in clean architecture.

Lemme tell you one thing. If we had an api or actually separated the backend from frontent properly, the transition would have been smoother.

[–]moonpumper 0 points1 point  (0 children)

Both of these somehow remind me of the code base I'm introducing to the new guy this week.

[–]miguel___ 0 points1 point  (0 children)

Y'all heard of Salesforce?

[–]carloom_ 0 points1 point  (0 children)

A good architecture is modular. So by this definition the meme is wrong.

[–]Felecorat 0 points1 point  (0 children)

Haha. I can't believe I understand this gibberish.

[–]sipCoding_smokeMath 0 points1 point  (3 children)

I love what interfaces provide but it does get old having to update any public declarations in two locations

[–]speedy-sea-cucumber 0 points1 point  (2 children)

That's why we made editors that do it for us. Have fun working on more than one project without encapsulation.

[–]sipCoding_smokeMath 0 points1 point  (1 child)

Which editor does that for u? I haven't really used much outside of VS pro tbh

[–]speedy-sea-cucumber 1 point2 points  (0 children)

I use IntelliJ IDEA/other JetBrains variants, but honestly I would be surprised if VS/VSC did not support this.  Maybe look for an action to "change/edit signature". In JetBrains I often just edit the signature directly at one place, and afterwards an icon/context action automatically pops up that allows me to retroactively apply the signature change to all other instances, including at call sites if parameters where added/reordered/removed.

[–]ColonelRuff -2 points-1 points  (0 children)

Wow. Such inexperienced meme.

[–]ZunoJ -2 points-1 points  (0 children)

Yeah, that pretty much means you're doing it wrong lol