-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Comments] OMG YES #8
Comments
@JohnnyWalkerDigital btw can you advice something to replace "small classes" with? I am not a native speaker unfortunately, and some wording maybe kinda incorrect |
💯 👏 My favorite quote regarding cognitive load in code development is
YOU might be able understand a challenging code base, and remember links, abbreviations and “historical reasons”. Your colleagues don't. Neither will you, in a year from now or after a job change. Writing code and designing software architecture that meets complex requirements, but is still readable and easy to understand, is something that will ultimately help both your colleagues and yourself. |
I've just never heard the advice "classes should be small" before. It makes no sense to me taken literally, so perhaps I'm misunderstanding it. Classes should have a single responsibility, and maybe that's what it's referring to? Even if "classes should be small" is referring to ensuring that your single responsibility class doesn't sprawl (which makes some sort of sense -- I'd still not use the word "small" personally, because I think it puts the emphasis on the wrong place, which would really be about "responsibilities" growing), it wouldn't sit in your article where it does, as there's never a situation where this would be bad... If there's one thing to improve your code/reduce cognitive load, adhering to SRP would be it. It's all about keeping things simple and reducing interdependencies... both of which are in line with your article. Personally I'd remove that reference altogether. And also I'm not really sure of a context where classes and methods could be used interchangeably... but maybe that's me? |
@JohnnyWalkerDigital > I've just never heard the advice "classes should be small" before. Chapter 10: Classes The second point makes sense of course, but again, people tend to emphasize too much on the 1st point |
Proper discussion with answers which exactly show the point: some developers suggest to keep »classes as small as possible« to have glorious »clean code«: https://softwareengineering.stackexchange.com/questions/125357/keep-my-classes-and-methods-as-small-as-possible |
@pixelbrackets Yes indeed. That illustrates the point very well and I agree with the answers that say "small classes" is a useful and helpful intention... expressed poorly. I cracked open my copy of Clean Code to take a look. As you might expect, Uncle Bob fills the confusion gap very succinctly:
As with all programming best practices, people who struggle with them usually do so because they've misinterpreted them. Edit: Hmm, re-reading "Too many small methods, classes or modules" (had to skim read before). Not sure I agree with that entire section to be honest. It sounds like someone taking small classes to an extreme. The idea that one class should have many responsibilities, and that long complex methods are preferable to shorter ones, flies in the face of my experience. Sounds like I should read "A Philosophy of Software Design" :) |
We can continue discussion if you don't mind :)
That's not really what I had in mind. Maybe some article modifications are needed 🤔 By no means this is a call to write god objects with many responsibilities |
Ok, I've just learned more about John Ousterhout's work. I think I understand why I was having so much difficulty Too many small methods, classes or modules. However, I also agree with Robert Martin's arguments that classes should have single responsibilities...! There must be a middle-path. Let's see if I can communicate why, or even if what I'm about to say makes any sense...! As you know, Ousterhout is concerned with the cost of complexity, and he talks about how Deep Modules are preferable to Shallow Ones. He says that a simple interface with complex functionality is more desirable than vise versa... and it's hard to disagree! For him it's about the cost of complexity vs the reward. So, if we have to pay 1 mental unit (representing cognitive load) to use a module's interface, then it would be great to get 10+ mental unit's worth of functionality in return! Similarly, if an interface is extremely complicated, but offers little in functionality, then we might pay 10MU to get our heads around the interface in return for 1MU functionality. Not good. But if we had to pick one out of the two, I'd say that the most important is the interface. Yes, taken literally then both are equally important, but in practice the more complicated the interface, the less likely a net positive outcome will be. We don't ever want to be in a situation where we're trying to add functionality to justify a complicated interface in order to balance Ousterhout's equation(!) Plus our brains don't appreciate the reward element: A complex interface is a complex interface. Therefore, we should all focus our programmer mental energy on writing simpler interfaces that hide the most amount of complexity it can. Which brings us to Bob Martin... I think when Martin wrote, "the first rule of classes is that they should be small. The second rule of classes is that they should be smaller than that" he wasn't talking about the functionality of the classes. He was talking about the interfaces. That is to say: He was trying to simplify a class to the point where the complexity cost for using it was reduced as much as possible. As he wrote in Clean Code:
And:
In other words, just like Ousterhout, his concern is with reducing the cognitive load on the programmer. As he states:
I would say that Martin is arguing for the same thing as Ousterhout. Unfortunately this has been misconstrued into abstracting things to an absurd level: "If it can be abstracted into its own class, it should be". I wasn't even aware that people had come to this conclusion from reading Martin's words. I believe that both Ousterhout and Martin are equally concerned with simplifying interfaces in order to reduce programmer cognitive load, but Martin's goal was lost in translation. People have been blindly applying Martin's words without thinking about the supposed benefit. Ousterhout reframing this same concern another way helps highlight this danger: you can go too far and abstract things to where your interface costs more than the functionality you get back. I've never been taught to abstract to such a destructive granular level -- but now I'm aware of it, I don't think your examples really explain the problem clearly enough. (Sorry!) If it did, I would have wholeheartedly agreed with the point you were making. I know you'd like to me to try and offer suggestions for a clearer way to explain what Ousterhout calls "classitis" (ie. an abundance of shallow classes). I will mull it over! What do you think? 🙂 🤔 PS - I love John Ousterhout now! Thanks for making me aware of his work. |
I'm a product owner not a developer and even for me this hit the nail on the head. I work on projects where my dev team is constantly changing so overly complex structures make the learning curve for each new team member that much more difficult and the time to usefulness as a team member that much longer. |
Together with @nkopylov we've just added a conclusion, hope you like it:The intricate and multifaceted nature of cognitive load within the realm of comprehension and problem-solving necessitates a diligent and strategic approach in order to navigate the complexities and optimize mental capacity allocation. Do you feel it? The above statement is difficult to understand. We have just created an unnecessary cognitive load in your head. Do not do this to your colleagues. Do not code in gibberish. |
I read that, thought that soberly academic and complex. Then realized that
was a demo. I like it!
…On Fri, May 26, 2023, 15:10 Artem Zakirullin ***@***.***> wrote:
We've just added a conclusion, hope you'll like it:
*The intricate and multifaceted nature of cognitive load within the realm
of comprehension and problem-solving necessitates a diligent and strategic
approach in order to navigate the complexities and optimize mental capacity
allocation.*
*With the above statement we have just created an unnecessary cognitive
load in your head. Do not do this to your colleagues.*
*Do not code in gibberish.*
—
Reply to this email directly, view it on GitHub
<#8 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BADUJD2SEWI2VRQJHMWELH3XIC2T5ANCNFSM6AAAAAAYOWBDSQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
@pixelbrackets I believe that with the conclusion above we conveyed the main idea of your quote as well :)
|
@JohnnyWalkerDigital Thanks for such a throughout analysis! Really, you have a very strong grip of the topic. Sorry it took long to respond. We definitely need to refine this section, because more and more people are asking questions about this exact section.
I think he wasn't talking about interfaces. I believe he was talking about the implementation. He was talking the exact same thing about small methods. This topic was greatly covered here.
That would be so nice, please proceed! |
For starters I have provided deep module example from John Ousterhout's book |
This isn't an "issue" but I just wanted to write a note of support 🎉
A lot of the useful tips and tools mentioned in this document are worth learning and using. OOP, Design Patterns, DDD, small method lengths (side note: never heard anyone say "small classes" -- that one makes no sense to me) are all extremely helpful in the pursuit of easily maintainable/extendable/scalable code... IF they're applied correctly.
I guess the issue is that you might need to apply them incorrectly a few times to learn their benefits.
But as I see it, a general rule of thumb is: Is the thing I'm trying to apply to my code making my FUTURE life harder or easier? When I return to this codebase in six months and have completely forgotten why I made the decisions I did, is the thing I'm trying to apply now actually going to make it easier for me to get back into it?
Or: Is it OK to leave this method long, breaking that recommendation, as long as the method is well-structured, has clearly understandable variables and logic, and has comments to explain what's going on?
You just want to make your future life as easy as possible for yourself (which also makes it easier for your follow team mates).
Rather than trying to be clever, using obscure functions and trying to reduce the number of lines of code, we should be focussing on reducing the number of lines you need to scroll up in order to understand what's going on. That's a much better goal than playing code golf with yourself/your team.
Impress me with how BASIC you've made everything (and, when applied correctly, the recommendations mentioned in this article with HELP with that).
The text was updated successfully, but these errors were encountered: