Live data from Hacker News

I don't love the single responsibility principle

sklivvz.com

91–100 of 125 posts

Re: I don't love the single responsibility principle

#91
post #76

Earlier quoted context omitted.

My beef with plain functions is that you can't mock them properly. But apart from this, yes. Referential transparency as much as possible.

What situation would require to mock a function ?

Maybe I'm not interested in testing what the function does? But yes, for pure functions, it's kind of a weak argument. More generally, you can't really swap a different implementation in place.

Re: I don't love the single responsibility principle

#92
post #24

I like many of the author's points. Pragmatism, thinking instead of blindly following principles, pushing back against size as a metric for measuring responsibility. I think Robert Martin's work absolutely deserves examination and critique. However, I don't share the author's definitions of simple and complex. Stating that "binding business rules to persistence is asking for trouble" is flatly wrong. Au contraire, It…

I too identify strongly with Rich Hickey's view on this. That's not to say Uncle Bob is wrong, but I don't think he is as clear a communicator. I see Uncle Bob as having a lot of wisdom that he is able to apply based on his experience but which becomes very hand-wavy when he tries to explain it.

UB happens to be flatly wrong. UB says that docucomments re-stating what the simple function does are excessive and bad. This is totally wrong when one looks at the generated documentation, but UB doesn't seem to use the documentation much. He seems to be one of the people who prefer digging through the code, even if presented with sensible API documentation.

Re: I don't love the single responsibility principle

#93

In an OOP design where objects already encapsulate both state and behavior, describing the ideal state of affairs as "single responsibility" seems kind of optimistic.

I think "state and behavior" is a bad way of thinking about it; in OOP design objects provide behavior. Its true that they encapsulate state, but the state (ideally) is simply that state necessary to provide the intended behavior. The behavior covers the area of responsibility, the state is part of the implementation of the behavior.

That's still a lot of state. How do you know an object is in the right state to perform its behavior? Well, acting as some other object you have to either read the first objdct's state or model it internally. And now we're coupled on state and behavior.

So what if the first object ensures that it's always in the right state to perform it's behavior? Well, now it's observationally equivalent to a state-free actor. Why did you involve state in the first place?

Because languages make it hard to not do so?

Re: I don't love the single responsibility principle

#94
post #92

Earlier quoted context omitted.

I too identify strongly with Rich Hickey's view on this. That's not to say Uncle Bob is wrong, but I don't think he is as clear a communicator. I see Uncle Bob as having a lot of wisdom that he is able to apply based on his experience but which becomes very hand-wavy when he tries to explain it.

UB happens to be flatly wrong. UB says that docucomments re-stating what the simple function does are excessive and bad. This is totally wrong when one looks at the generated documentation, but UB doesn't seem to use the documentation much. He seems to be one of the people who prefer digging through the code, even if presented with sensible API documentation.

I understand he's a polarizing figure and is overly prescriptive of things that are a matter of style, but his stance on documentation doesn't seem germane here.

Re: I don't love the single responsibility principle

#95
post #24

I like many of the author's points. Pragmatism, thinking instead of blindly following principles, pushing back against size as a metric for measuring responsibility. I think Robert Martin's work absolutely deserves examination and critique. However, I don't share the author's definitions of simple and complex. Stating that "binding business rules to persistence is asking for trouble" is flatly wrong. Au contraire, It…

Unfortunately here, Rails encourages putting each class into a separate file, so you have 10 classes spread over 10 files, which does increase complexity. I dislike having a class/module per file.

Why do you say it increases complexity?

If I'm in extreme mode I take the view that each file should be a single screen. That means a tangible reduction in the complexity of working on them (no more scrolling - each class is just in its own tab).

Re: I don't love the single responsibility principle

#96

Earlier quoted context omitted.

Couldn't have said it better. Classes are useful, but only occasionally so. About the only time I find myself using classes is when there's several functions that have a very strong relationship to a particular portion of state (like when using an ORM). The rest of the time it's referentially transparent functions.

My beef with plain functions is that you can't mock them properly. But apart from this, yes. Referential transparency as much as possible.

This is highly dependent on your language. A language where functions can be passed as values allows functions to be injected as parameters (for polymorphic behavior). In Clojure, you can even replace a function definition just for unit tests without dependency injection at all.

For example, with-redefs. This allows you to replace a given function anywhere in the whole codebase with any lambda. This rebinding only lasts inside the scope of the s-expression. When I realized that, I realized everything I knew about DI and interfaces were just hacks of incredible complexity to get around a poor language that wasn't built to allow unit testing. I now think it's impossible to have both unit testing and a good design in Java/C#. Neither were made to be easy to unit test, it wasn't even a concept when Java was made.

In C#'s defense, there is a way to mock a static function by replacing it using the Mocks library. To MS's shame, that library requires the 13k edition of Visual Studio. When I realized that, I realized I want to leave C# for good. I'm not interested anymore in a language that resists testing so much I have to choose between an easy to understand design and unit tests.

Re: I don't love the single responsibility principle

#97
post #76

Earlier quoted context omitted.

What situation would require to mock a function ?

Maybe I'm not interested in testing what the function does? But yes, for pure functions, it's kind of a weak argument. More generally, you can't really swap a different implementation in place.

I answered this in my other answer to you: https://news.ycombinator.com/item?id=7709395

It's a common misconception that interfaces are the only way to do polymorphism, because that's usually the only way in Java.

Re: I don't love the single responsibility principle

#98
post #72

Earlier quoted context omitted.

Unfortunately here, Rails encourages putting each class into a separate file, so you have 10 classes spread over 10 files, which does increase complexity. I dislike having a class/module per file.

In Django (the closest thing Python has to Rails) the convention is to put all your models in one models.py file. I also prefer it this way.

Having worked with both, there's a trade-off. Given that in Django you're (mostly) explicitly importing classes and modules rather than autoloading, it's handy to have them all in one place. OTOH, when your project grows, you end up with enormous model files (especially if you follow the fat models/thin views pattern). So you then have to split them into different apps, so fragmentation slips in eventually anyway. (In a rails project, unless you're bolting on engines and such, all your models are at least in one folder).

Where I definitely do prefer Django in this regard is that models declare their data fields, rather than them being in a completely different part of the source as in AR (not Mongoid, I now realise). Do I remember the exact spelling I gave to every column when I migrated them months ago? No. It's good to be able to see it all in one place rather than having an extra tab to cycle through. I don't see any practical benefit from decoupling here.

Re: I don't love the single responsibility principle

#99
post #80

"The purpose of class is to minimize complexity" "The purpose of class is to organize code" "A class should have one, and only one, reason to change" What? What about: "The purpose of class is to encapsulate state". If there is no inner fields in class, there is no reason for class. There is no state. One or more fields in class means that they make sense when looking at all of them together, as a "state". If some me…

Do you see "having a state" as "being able to change state" ? Because classes may be used to represent concepts or objects from the real world. Some of them may not have a changeable state but inner fields certainly.

Re: I don't love the single responsibility principle

#100

Earlier quoted context omitted.

My beef with plain functions is that you can't mock them properly. But apart from this, yes. Referential transparency as much as possible.

This is highly dependent on your language. A language where functions can be passed as values allows functions to be injected as parameters (for polymorphic behavior). In Clojure, you can even replace a function definition just for unit tests without dependency injection at all. For example, with-redefs. This allows you to replace a given function anywhere in the whole codebase with any lambda. This rebinding only la…

Hm, that may be true for Clojure (or Python, as long as you don't redefine anything important), but I wouldn't how to do that with Haskell, for instance.
Post reply on HN