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

Thank you for taking the time to reply, instead of just hitting downvote. I feel like if we argued over a beer we’d probably end up agreeing on a lot of things. But let’s start by disagreeing. :-)

> "Does this have one responsibility?" really isn't the right question to ask.

It’s a great question to ask. As a senior engineer, the answer might be “no”, but there’s a vast difference between code where the answer is “no” because someone made a conscious choice, vs code where nobody even asked the question. Here’s the thing: a compiler and linker can join ten classes into a single executable, but even a senior engineer cannot look at a single class with ten responsibilities and figure out what the fuck is going on. There’s a doc at my company that describes the core function of one particular service. The doc describes the simplest of systems and so you would be surprised to learn that 1) it took me two years of working one the product before I could write it and 2) nobody knew. The reason it took two years was because there were 10 different pathways, and every pathway was just a giant implementation, each written differently, and each, ultimately, doing the exact same fucking thing. But you’d never be sure just by looking at the code. In fact it very much looked like each of these things had very specific things that they did differently. Over two years, while also doing my job of keeping this thing running and adding features, I refactored the thing to be SOLID. In doing so, demonstrated that they all do the exact same thing. We haven’t finished refactoring everything, but we do now test all the pathways with a parallel implementation that verifies 80 classes and 500 instances at runtime with one class and ten instances.

I work on software that you and most people on planet earth with at least a mobile phone are using in one way or another. I have made many pieces of this system better by evolving a clusterfuck of cohesion into a system that is easy to reason about, maintain and evolve - by apply SOLID principles.

I’m currently working on a package used by over 1,000 services. The most pain has been caused by previous iterations ignoring the open-closed principle. As you say, “easy to modify and delete”. A stronger rule, which perhaps you’re alluding to, is don’t allow any extension at all, and just expose only interfaces. In that sense I could agree open-closed principal is moot, but it’s moot for taking its argument to the logical conclusion.

I am also a fan of DDD, and for the reasons you allude to: the second half of the book is more about communicating in a large engineering organization.



> I feel like if we argued over a beer we’d probably end up agreeing on a lot of things. But let’s start by disagreeing. :-)

Definitely! :D

Re: SRP, my issue is that it's too subjective. Even for a very simple code snippet like `foo.x = bar.x`, it's not clear whether this covers one responsibility (copying bar's x to foo) or two responsibilities (retrieving bar's x and then setting foo's x). An experienced programmer has enough intuition to understand which of these options is better based on context, but SRP is supposed to be guidance for novices. Maybe I'm asking too much from a one-sentence piece of advice, but maybe splitting up code well requires more than one sentence worth of guidance, and I think SRP boils things down beyond the point of usefulness.

SOLID was invented by Bob Martin, and one of my issues with Martin's style is that he breaks his code into pieces which are far too small. He likes to write methods which are only 2 or 3 lines. Clearly this feels to him like the natural size for a "single responsibility," but to me, he's splitting up highly cohesive code into a profusion of tightly-coupled micro-functions, and I find the result barely legible. This, more than anything, has convinced me that the "one responsibility per function" guideline is just too flexible to be useful on its own.

> I have made many pieces of this system better by evolving a clusterfuck of cohesion into a system that is easy to reason about, maintain and evolve - by apply SOLID principles.

SOLID can describe good code (at least to some degree), but I don't think it's very good at at explaining how to improve code. You're an experienced engineer with good intuition: You see a piece of bad code, you know in your gut what it needs to be changed, and then the final product ends up being SOLID. But if you show the bad code to a junior developer and tell them only, "make it SOLID," I think they'll be lost. They don't have the instincts that tell them whether it's more appropriate to describe a method as having one responsibility or two, or whether they've split things up too much.

> In that sense I could agree open-closed principal is moot, but it’s moot for taking its argument to the logical conclusion.

I'm not sure I follow. My point is that, rather than writing `Foo` in such a way that it's easy to write `FooWithLogging extends Foo`, it should be written in such a way that it's simple to throw away the original `Foo` and write a new version that has logging built in. If you're always extending Foo through inheritance, you end up with a whole string of Foo variants, each piling new features haphazardly upon its parent. Conversely, if you're willing to go back to the drawing board for every new feature, you can evolve a sensible architecture to accommodate any number of features. Of course, if your library has a lot of customers with highly divergent needs, it might be worth building for extensibility, but I don't think that should be the default strategy.

> The most pain has been caused by previous iterations ignoring the open-closed principle.

How so? Injecting new features without adjusting the surrounding architecture to accommodate them naturally? I agree that's a problem, but I feel like extension-by-default also leads to this, since it doesn't give you the opportunity to adjust the original implementation.




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

Search: