5 ms·
Sadly article's author doesn't touch the main idea of the book: component's public API should be narrow as possible. John makes a great deal of that with concre
by bvrmn 2y ago
Sadly article's author doesn't touch the main idea of the book: component's public API should be narrow as possible. John makes a great deal of that with concrete examples.
- ilrwbwrkhv 2y agoThis. That is the biggest idea and also the most applicable and the easiest to understand when your complexity is going through the roof. For example in Ruby land it is very common to make a class and then make a lot of small tiny methods which are one liners or two liners. I had asked him directly about this and his answer was to avoid doing it. Since then my Ruby and Common Lisp code has become much better. I have since moved to rust, but the point still applies.
- theonething 2y ago> make a lot of small tiny methods which are one liners or two liners. I'm presuming you mean public tiny methods? Having private ones like that can be good if makes sense to do so (encapsulates logic, increases readability, etc)
- ilrwbwrkhv 2y agoYes public "deep" methods. But even private methods I have been more conservative. It is after all an API for you! Basically the idea that you shouldn't have long methods is something I don't believe in anymore. Even Carmack made a similar point: http://number-none.com/blow/blog/programming/2014/09/26/carmack-on-inlined-code.html http://number-none.com/blow/blog/programming/2014/09/26/carm...
- lll-o-lll 2y agoI never believed this, even when I was compelled to do it. What are we achieving in these plethora of small methods? There are many potential negative patterns that eventuate. - Lifting variables into “global” (object) state. In more complex classes, it’s often hard to even identify that this has happened. Is this permanent object state, or just an internal temporary variable that made it easier to leap around methods? - Making code harder to change as variables must be lifted into method parameters (so changing a variable, or adding a new one leads to multiple modifications). Method1 calls Method2 calls Method3 with a “dependency” that Method2 never needs. - Poor naming leading to obtuse code. DoThingPart1, DoThingPart2 - Harder to follow code by having to jump around the file (or worse, multiple files). There are better and worse ways to structure code to make it easier to read and reason about, however blind metric approaches are not the way.
- nyrikki 2y agoI don't remember anything about lifting state up in the clean series, was it perhaps a react specific book? To me that would violate the dependency inversion principle that most of the books leverage heavily. I know that some languages like .net encourage those Singleton classes, but I would appreciate being pointed at where the clean series sells this. I am of the bounded context camp for component sizing in general so it is likely I skimmed and dumped the concept, like I did with the over reliance on polymorphisms, which is a sometimes food in my mind.
- whstl 2y agoTo quote from Clean Code: "The function is a bit too long and the variables are used throughout. To split the function into smaller pieces we need to create a GuessStatisticsMessage class and make the three variables fields of this class." - Add Meaningful Context, Page 28 EDIT: And then right below there's an example where the author lifts variables into object state. EDIT 2: Funny enough, ChatGPT managed to refactor to something even much shorter and IMO much clearer than both examples in the book: private void printGuessStatistics(char candidate, int count) { if (count == 0) { print("There are no " + candidate + "s"); } else if (count == 1) { print("There is 1 " + candidate); } else { print("There are " + count + " " + candidate + "s"); } }
- nyrikki 2y agoThank you for doing the work to find that for me. I still don't see that as: > "Lifting variables into “global” (object) state" It is simply the inversion and extraction method that is commonly used. The value of it is lost here as his example is poor IMHO as I find that cleaning up deep nested arrow code is where it is. This method on page 28 is about refactoring to improve readability, and the location where the variables are declared are still in the same class. Nothing has changed in that example except adding named private methods in place of logic inside an if-elif-else ladder. So this: if (count == 0) { number = "no"; verb = "are"; pluralModifier = "s"; } else if (count == 1) { number = "1"; verb = "is"; pluralModifier = ""; } else { number = Integer.toString(count); verb = "are"; pluralModifier = "s"; } Is changed to this: if (count == 0) { thereAreNoLetters(); } else if (count == 1) { thereIsOneLetter(); } else { thereAreManyLetters(count); } Remember this chapter is about "name things" not flow control or even data flow. It actually is intended to help with most of the concerns above and has nothing to do with the react style anti-parameter drilling style of 'lifting' If you go to page 97 he goes over the 'The Law of Demeter' and argues against exactly what was above and actually cites Martin Fowlers refactoring book which is written in a far better style and tries to call out nuance. So my opinion that he gives semi-helpful advice that he over sells as received wisdom still holds. Obviously the cost of calling a private method in your language and how that impacts your use case matter here.