Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I had to look up what SOLID is, and it kinda goes against most of what we’ve learned about software development since the 90s. When people say they don’t want algorithmic “leetcode” interviews, I wonder if this is the alternative they want? 1999 style OOP Java trivia?

Is the idea that you’re supposed to provide good discussion of the pros and cons, and so show some experience? That sounds like you’ll just hire people who had similar experience to you.



SOLID is a meaningless term in my corner of the industry (firmware, where we follow the SPAGHETTI method), so I read SOLID as a placeholder for whatever the acronym-of-the-week is. With that in mind, I came to a totally different conclusion. I want to ask questions that most interviewees get wrong, because that's how you narrow down a large pool of candidates to a small pool of finalists. Augmented by a reasonable quantity of questions, pointed questions like these can serve to isolate a signal from noise.


> firmware, where we follow the SPAGHETTI method

I used to write GPU device drivers. Electronic Engineers had a great understanding of the hardware, but tended to write sloppy spaghetti code. CS graduates, on the other hand, had a loose grasp of the hardware but we're better at writing solid maintainable code. Most teams ended up with a healthy mixture of the two, which worked great.

I once ran into a hiring manager that only wanted to hire people like himself, with the same skills and philosophy. I tried explaining why we needed people with a more diverse set of skills and strengths, but he wouldn't bulge. Unsurprisingly his team didn't deliver much value to the company.


It's a weird field in that regard. I'm a CompE, but I started college as an EE and switched pretty late. My skillset is more closely aligned with the CS folks, but my formal education and training was by EEs, for EEs. I still do "hardware stuff" for fun.

The best firmware teams I've worked on have always had a mix of disciplines. Heck, I mentored a mechanical engineer for a while (he became a very good firmware dev). You have to have good programmers who manage to write modular, maintainable code even if the language and hardware limitations fight them the whole way. You need folks who understand Electrical Engineer-speak. Depending what you're doing, you might HDL people, and that stuff might as well be a completely separate discipline from regular software. You need people who are comfortable debugging with nothing more than log messages, and if you're lucky, a coredump. You need a manager who can wrangle the occasional "it's a hardware problem" vs "it's a firmware problem" debate.


Yep, that matches my experience. There was a lot of Feynman debugging as well. It's a good job for somebody who is eager to learn new stuff and get out of their comfort zone. Another great thing about it is that people tend to stick around for a long time, so you build good friendly relationships with your coworkers.

The biggest downside of driver development is that it becomes very repetitive after a while: you are the maintainer of this immense complex piece of clockwork (the hardware) that you must to keep ticking reliably at all times by working around all the bugs in it. It sometimes feels like your beautifully crafted software contains as much code to track and work around hardware bugs as it contains code fof the idealized hardware described in the origibal documentation.


My first job was on working on drivers for a proprietary OS. Every time a new board came out, the protocol was to copy the code for the most similar board and start making modifications. It works, but there's a whole lot of repeated logic for common init sequences and logical mapping of memory addresses to what they control. The "simulator" that was widely praised for cutting down on spin-up time for a new board was nothing more than stub code. It all worked and was maintainable, but everything was harder than it needed to be.


> Every time a new board came out, the protocol was to copy the code for the most similar board and start making modifications

I only saw that happen at one place. It was a bit of a shitshow.

Big corps don't do that, they have a clear internal division between various levels of hardware-independent and hardware-specific components, down to workarounds for specific bugs in specific releases.


This is almost a word-for-word description of the dev workflow for a proprietary embedded OS I worked on as an intern. Even the "simulator" was what you describe - some #ifdefs that turn the program into a cli program using Win32.

This worked for us because our approach was to "make it right the first time, update only when necessary."


It's not completely meaningless but it does tend to be something people recite and then never think about - even when they're inadvertently following it. It's performative - a bit like reciting the bible.

Take I as an example - "don't depend upon interfaces which you do not use". I've seen good developers cut out dependencies hundreds of times for this reason - not because they've trained themselves on SOLID but because it just feels right after years of experience. If I said "this is part of SOLID" many of them would go "... is it?" "hmmm. I guess it is..."

As with reciting the bible, just because somebody recites it doesn't mean that they took it to heart and people who take it to heart can't necessarily recite it.

Being able to recite it is just a ritual used as a social signaling mechanism. It's a bit like leetcode, an ability to recite big O notation or knowledge of git's internals - symbols of "developerness" that don't necessarily align with skill.


I'm not crazy about SOLID principles either. They don't feel like useful, practical ideas to me. They were born to be memorized for a classroom test or a job interview. SOLID does come up in interviews, though.

Most companies don't really invest in trying to do good interviews. Rarely is there anyone motivated (or permitted) to think about the process and make it a lot better or different. Doing what they've always done, or what everyone else seems to be doing, is good enough.


DDD, Microservices, Clean, Hex, Onion, TDD, XP, EDA.....

All of those follow the basic SOLID principals.

The problem is the cargo culting and blog posts vs actually reading what the stuff means.

S or the Single responsibility principal as an example is always explained poorly by the same people who complain about it.

SRP means that "A module should be responsible to one, and only one, actor."

An 'actor' being a group that requires a change in the module.

making sure you decouple persistence code from domain code is an example. Almost universally the people who complain about SOLID thinks it means that you have to have trivial functions with lots of sprawl.

Really it is about allowing you to make changes without stepping on another's toes or trying to coordinate with them.


Mantras like these are always a response to something. Someone in charge of technical culture at $PLACE diagnosed specific anti-patterns in their Java code, came up with a set of rules for the noobs and a catchy acronym. Things got better. Great!

But then those rules got transposed into other situations, possibly by somebody else and things went downhill. Also see "Agile".

Our industry, because of its huge growth, is filled with inexperienced people who learned from inexperienced people. We all know software is kind of trash, and we're coming up with ways to improve it, but the fact of the matter is we don't know what works. We know some things that don't work, and many of those were previously on a list of things that might work and had catchy acronyms of their own. A few people have enough experience to give good advice, but what they have to sell isn't a magical silver bullet with a neat acronym, and they don't use twitter, so nobody listens to them.

The only thing I personally believe makes you write better code is long and varied experience with different domains, fueled by a desire to always be learning. Throw away mantras when they're no longer useful. Work like this for 10-20 years, and you'll start writing sort of OK code. Everything else ends badly.


> Is the idea that you’re supposed to provide good discussion of the pros and cons, and so show some experience? That sounds like you’ll just hire people who had similar experience to you.

This depends far more on the interviewers listening skills, open mindedness and maturity. Obvious everyone has their biases, but good interviewers (especially for senior positions) need to be able to evaluate how someone with different skills and perspectives will be additive to the team.


Your comment is involuntarily funny in the sense that 1999 style OOP Java is a serial offender of SOLID, not a prime example of it. It's mainly the Liskov Substitution and dependency inversion principles. If you have deep class inheritance hierarchies, you are not doing SOLID, sorry.


I’m not sure I agree encouraging inversion of control, more indirection and behavior inheritance is an improvement. In the recommended style of most languages, these are probably big anti-patterns.

On the other hand, I never spent that much time working on old Java stuff, so maybe it is a step in the right direction.


Any time you inherit from a concrete class (vs just implement an interface) you depend on something concrete and not an abstraction.


Hmm, SOLID is very well-known and the principles are ubiquitous good practices for object-oriented programming and also useful for software dev in general.

Certainly, asking about them and , especially, asking the candidate to critique them is a very good question.


Perhaps there’s a difference between knowing and having internalized these concepts, versus having heard of them via a particular acronym, and being expected to remember that acronym and these specific names.

“Liskov substitution principle” for instance is something I had to look up. I can read it and say, “oh, duh, yes that’s a key part of what interfaces are even for.” I’ve built with it for decades now.

The term SOLID was apparently introduced in 2004. It would be a shame to reject good programmers who can opine intelligently on these principles, but who have not internalized this particular jargon.


Yes, there is quite a difference in my opinion. What does SQL stand for? No clue, but I can write you an SQL query. Same thing with HTML, CSS, PHP, etc.


That's funny. I wrote SQL daily for 10 years, read the ISO standards when working on SQL transpilers, persistence frameworks for multiple databases, etc. Even wrote a new storage engine for MySQL once.

But I just had to look up what the acronym stands for! Apparently it's "structured".


Isn't that the point?

Even if the candidate doesn't know the acronym you can probe if they know and understand, and be critical of, what the principles are.


It’s generally not what it claims. Single purpose is a good idea, but the rest…

The idea that one class changing won’t change others is a pipe dream.

Substitution only matters if you’re using inheritance, but if you’re inheriting, you likely have bigger problems as few real world problems are naturally represented by inheritance.

The interface rule is redundant with the single principle idea. Maybe it should have been SOLD instead.

Dependency injection is a guideline at best. If you actually do what it says, you get enterprise fizzbuzz. It should only be used occasionally and sparingly at specific boundaries otherwise the cure becomes worse than the disease.

More controversially, when you avoid inheritance in favor of composition in a language like Java, you lose polymorphism while keep a leaky abstraction and really bad encapsulation while the language still retains all the mental and syntactic complexity of the inheritance bits.

https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...


> The idea that one class changing won’t change others is a pipe dream

Reality is never black and white but that's a good principle for good software design and worth at least aiming for.

If anything that has been adopted and generalised in microservices, etc. because encapsulation, modularity, design by contract all hinge of this same idea, which is powerful and useful.

That's why when discussing any "principles" the important is to get the core idea behind them instead of sticking to the letter and discarding them as useless.


Encapsulation is extremely important and pairs with single responsibility, but that’s completely orthogonal to OOP.

Once you are solidly in the composition camp, functions are immediately superior. They tend to be naturally single purpose and have mathematical rules that make them easy to compose.

Most function-heavy languages also adopted modules which provide a better, less-leaky abstraction too and that’s without getting into all the other advantages in the type system or better syntactic ergonomics from dropping all the OOP baggage.


Even in Uncle Bob's version of the single responsibility principle, 'one reason to change' is about people.

He words it poorly, but it is more about not commingling DBA, UX, core domain logic in a module.

People miss that and end up having low cohesion.

While SRP and interfaces do have an intersection, they are not the same.

Interfaces leaking implementation details is an example.

Composition, dependency inversion, and dependency injection are all forms of L.

Polymorphism is problematic in most cases but thinking it is the only way to accomplish that looser coupling goal is a misunderstanding of where we have grown with the concepts.

I tend to prefer the ports and adapters pattern, which ensures client components that invoke an operation on a server component will meet the preconditions specified as required for that operation.

That is equivalent to LSP or design by contract.

SOLID is just a set of principles that are intended to make loose coupling and high cohesion the ideal default.

This is in contrast to procedural code that we know makes unmaintainable systems.

The problem with SOLID is the same as Agile, XP etc...

People ignore the core ideas that are descriptive in nature and try to use them as oversimplified prescriptivist rules.

To be fair Robert Martin wasn't great at selling this and that is why I tend to point people to authors like Martin Fowler who are more careful about sounding like a preacher handing out laws.

But Robert Martin developed SOLID in the context of cohesion, and if you read it in that context it is valuable.

He didn't invent the SOLID tool to remember the rules, but it seems that blog posts and Wikipedia pages are as far as people get before trying to implement it or dismiss it.


Take a look at Uncle Bob’s code some day. You will then realize that all of his writing was synthesized solely to make him consulting money. His actual code is rubbish. This has been true all the way back to the 90’s with his inane questions to the OOP Usenet groups.


That's also my unpopular opinion about him, I thought I was alone. I watched some of his clean code videos in the past and thought his advice looked dated and very "enterprise" styled.


Back in the 1800's and early 1900's medicine was a very new science (in a modern sense), and snake oil salesmen abounded. Laymen had very little information to discern legitimate medical advice from quacks hocking piss and ink as a cure all.

We have the same problem now with software systems, although at the least we are advancing beyond the primitive stages and the charlatans are becoming more apparent.


I already stated he isn't like his books personally.

But outside of Tu quoque fallacies, van you explain why this is a bad idea.

"A module should be responsible to one, and only one, actor."


The problem is that Uncle Bob made up SOLID and other ideas more or less by cobbling random ideas from other people and selling them on the market as his own. As many others have mentioned here, pieces of SOLID kinda-sorta make sense, but it doesn't hang together cohesively because it was never created in a cohesive manner.

ALWAYS look behind the curtain at what software consultants are selling to what they have actually built, and then you can ascertain if they are selling you hard won engineering knowledge or a bunch of marketing BS.


As I want to learn, outside of the problems with cargo culting, why having the SOLID principals as the default _ideal_ when programming cause problems.

Sure he was pulling from Structural design ideas, which even Tom DeMarco, the author of the canonical book on SD, now says should have been iterative and Agile-like, but he was also pulling from papers like the following from 1972 about modularity.

https://dl.acm.org/doi/10.1145/361598.361623

The SOLID principles are a specific application of computer science principles to OO.

Separation of Concerns is a specific example of core CS principals that he pulled from but are from Dykstra.

https://www.cs.utexas.edu/users/EWD/ewd04xx/EWD447.PDF

So is your reason for discrediting him that he aspired to be a professional writer, or that he tried to collect concepts from the wider tent into a more domain specific presentation?

Because structural design is an example where the founders realized that not paying attention to that first paper was problematic.

"We have tried to demonstrate by these examples that it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart.

We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others. Since, in most cases, design decisions transcend time of execution, modules will not correspond to steps in the processing. To achieve an efficient implementation we must abandon the assumption that a module is one or more sub- routines, and instead allow subroutines and programs to be assembled collections of code from various modules."

How about addressing Robert Martin's position, instead of irrelevantly attacking random aspects of the person who is making the argument. A.K.A Ad Hominem fallacies.

In the context of this thread, if a candidate could only express their objections to _ideals_ that are intended to be the defaults, and couldn't express their objections in a way that related to business and customer needs, I would be a hard no on the hiring position.

It is OK to not agree with these ideals, but to only offer personal attacks to dismiss them, it indicates someone who will probably be a difficult team member and lack customer focus.

Ad Hominem's never address the real concerns or needs of a project and are simply not constructive.

We know that EA failed, we know SOA works better if imperfect, we know that aiming for loosely coupled and highly cohesive code results in systems that are easier to maintain and scale, and we know that with the rise of the cloud most needs will be distributed. All of those apply the same principles at a different scale or domain.

Hand waving away those well known concepts because you have a distaste for an author won't change that. But if you share ideas that address the limits of those ideas perhaps it can help move us further.


>The SOLID principles are a specific application of computer science principles to OO.

There's little to no hard science and serious research behind them, aside from Uncle Bob writing about them and some hazy papers.

The Liskov substitution principle was developed by an actual computer scientist working on such research, but the general field of programming methodology Liskov worked in remains scientifically something like what psychology was before Freud.

Not saying Freud is scientific - saying that programming methodology is even less well established and researched scientifically in 2024 that psychology was not just at the time of Freud, but even before Freud.

Dijkstra himself, in many of his notes regarding methodology, was basically 90% opinion, even when he was right.


Here is a metastudy that will show that complexity, coupling and size were found to be strongly related to fault proneness.

https://arxiv.org/abs/1601.01447

There is lots of studies that show that modularity is one of the most significant factors for evaluating maintainability of OO systems.


Note that even before EA was dead, modularity was still valued as captured by this best practices guide that I am pretty sure is older than 1991.

https://www.washington.edu/is/fin/fas/standards/cobol.html

R.Martin had nothing to do with those rules related to procedural code.


> Substitution only matters if you’re using inheritance, but if you’re inheriting, you likely have bigger problems as few real world problems are naturally represented by inheritance.

No, it matters when you implement interfaces (in the Java sense) too.

Tons of real world problems are naturally solved by having multiple implementations of interfaces. Also, Dependency Inversion doesn't even make sense without it.


It’s well known in a specific setting, possibly? I’ve managed to never hear of it in 18 years.

If asking “well known to some people” stuff is kosher, should I be able to quiz candidates on FFP design principles in Haskell, or maybe how to implement collision detection in a video game? Both of those are well known in swaths of the industry.

I guess if you’re hiring for a specific role, writing OOP business applications, you will have no shortage of candidates who know about SOLID, but you’re probably passing on everyone who is changing domains.


Only ones I ever found worthwhile are D and maybe I.


The only part of SOLID that is unquestionably correct is "L" - it is the only sane way to use subclassing in OO languages.

"D", when used judiciously, can be useful because it can make unit tests much easier to write. But when used too much, it results in incomprehensible code.

But as for "I", in my humble opinion, when you find yourself reaching for it, it's a sign that the code base is already poorly organized.


But the L part is only correct in so far as it repeats the definition of what it means to be a subtype, i.e. it is vacuously true.

BY the way, does any OO language apart form Ocaml get this right?


The L part was apparently not so obvious to the authors of the Java standard library since it has violations all over it.

Readonly implementations of java.util.List come to mind.


S (Single responsibility principle) is very important, not only for OOP but for good, maintainable software design in general (yes, even if you do firmware stuff).


Absolutely. I just find it rather inactionable, as it can be subjective.


Odd because that's arguably the easiest to apply when designing software.


>Certainly, asking about them and , especially, asking the candidate to critique them is a very good question

...if you're looking to hire a code quality consultant that has not written any code since the 90s


If you think those principles got out of date then indeed I would not hire you.

Something like the "single responsibility principle" is just good software design to anyone who ever had to maintain any piece of software.

Quite extraordinary how commenters in this thread discard things as old without even understanding that core principles are as valid now as they were then.


>If you think those principles got out of date then indeed I would not hire you

If you think your hiring criteria are some kind of general yardstick, I wouldn't want to be hired by you in the first place. What's with people using their position of power (hiring people) as some kind of argument - or perhaps threat?

>Something like the "single responsibility principle" is just good software design to anyone who ever had to maintain any piece of software.

The "single responsibility principle" is an ad hoc, ill defined idea. A bad idea for many real world cases, that has to be applied with discretion - not taken as a core guiding principle. Not to mention that neither "reason to change", nor "change" is well defined by Martin.

It's as bad one-size-fits-all advice as advising about the ideal function being "two to four lines of code long" (also by Martin) - leading to crappy, hard to follow code, and needless abstraction.

KISS - now that's a principle I would get behind.


A principle always has to be applied with discretion.

Hence why I think why the OP's idea to ask candidates to critique is good. It shows whether the candidate blindly follow things as the gospel or is able to articulate limitations but also the reason behind a "principle" because there are very good reasons behind them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: