I can't access the linked page without accepting cookies.
Want cleaner code? Use the rule of six
121–130 of 352 posts
Re: Want cleaner code? Use the rule of six
#122Earlier quoted context omitted.
Right?! That should instead be -len("foo") or -NUM_PREFIX_PARAMS
That doesn't improve anything in terms of knowing why the number is there.
Re: Want cleaner code? Use the rule of six
#123«Every line does only one thing» - that’s not related to real clean code. And there are bunch of languages that’s OK to have few things on the same line - perl, ruby, groovy, scala and even php.
Re: Want cleaner code? Use the rule of six
#124I don't necessarily agree with the step of putting the code in a separate function; that often works, but just as often makes it so that the code can't be read top-to-bottom anymore which hurts readability. In this case there's, I think, a better alternative; the equivalent-ish code in Ruby for the example code here would be something like this: values = s .partition('?')[-1] .split('&') .map { |key_value| key_value.…
Re: Want cleaner code? Use the rule of six
#125This rewrite is more performant than the original: query_params = s.split('?')[1].split('&')[-3:] map(lambda x: x.split('=')[1], query_params) The calculation of query_params, having no dependency on the lambda parameters or anything being mutated, has been lifted out of the lambda, and thus spared from repeated execution by map. The compiler for that language won't do this automatically.
What? No it isn't! You didn't parse that correctly. The query params were never in the lambda to begin with. Python function calls have strict (not lazy) semantics, i.e. "applicative order", i.e. both expressions passed as arguments to map() are evaluated before the map body gets them as parameters, thus the query params would only be evaluated once, even when inlined as they were originally. Same with the lambda def…
Re: Want cleaner code? Use the rule of six
#126Re: Want cleaner code? Use the rule of six
#127Reminded me of 'Object Calisthenics' by Jeff Bay. Basically an exercise for a toy project where you adhere to 9 rules: 1. Only One Level Of Indentation PerMethod 2. Don’t Use The ELSE Keyword 3. Wrap All Primitives And Strings 4. First Class Collections 5. One Dot Per Line 6. Don’t Abbreviate 7. Keep All Entities Small 8. No Classes With More Than Two InstanceVariables 9. No Getters/Setters/Properties https://william…
> 1. Only One Level Of Indentation Per Method
One level of indentation just leads to an explosion of tiny one-use methods with weird names, and now you can't read the code linearly. You will almost certainly never reuse these tiny methods, especially since you're likely consigning them to an instance of a class instead of a free function, so all you've done is forced people to jump around a lot.
> 2. Don’t Use The ELSE Keyword
Not using the else statement just obscures the fact that there's a branch in the code. Obscuring something important seems to be the opposite of what you should do.
> 3. Wrap All Primitives And Strings
Ugh, that seems verbose and clunky, especially in a language like Java without operator overloading. I'm all for type aliases or typedef's, or, creating a class if the builtin primitives don't work (I think a Money class makes sense because you don't exactly want to use a float, for instance). But just putting wrappers all over the place sounds grotesque.
> 4. First Class Collections: Any class that contains a collection should contain no other member variables
Why even have a class then? Why not just have functions that operate on a collection? It's much more generic that way, since if you're using iterators or an abstract collection interface, you can potentially allow the user to choose the exact data structure, and you avoid the ceremony of creating a new type that's again just a wrapper.
> 5. One Dot Per Line... Basically, the rule says that you should not chain method calls.
This is the first one I roughly agree with, but I wouldn't consider it a hard rule. Chaining .map and .filter together for instance is a very common pattern.
> 6. Don’t Abbreviate
min/max is just as clear as minimum and maximum. I'm not using "index" in my for loop when "i" will do. "n" is perfectly well understood as a count of things. Abbreviations when used properly make code easier to read, not harder.
> 7. Keep All Entities Small... No class over 50 lines and no package over 10 files
Ok, assuming the problem can't be simplified, all you've done is now fractured all that functionality into tens/hundreds of files. How is that easier to follow? Sure, there's balance in all things, but I'd probably rather read a 1000 line class than 20 small files split over 2 packages.
> 8. No Classes With More Than Two Instance Variables... I thought people would yell at me while introducing this rule, but it didn’t happen
They were being polite. I'll do it for them. What the fuck?
The example he gives is also awful, where instead of using a string for name, he makes Name a type (ugh) with FirstName and LastName. Not only is that overly ceremonial, but it's wrong, there are plenty of names from various cultures that do not fit cleanly into FirstName and LastName. Also, what happens if he wants to store a MiddleName? That's three instance variables! Ohno! OR what if the person has like 10 middle names (this shit happens). Are we going to have 5 nested data types for that?
> 9. No Getters/Setters/Properties ... My favorite rule. It could be rephrased as Tell, don’t ask.
My brain feels like it's going to explode.
> It is okay to use accessors to get the state of an object, as long as you don’t use the result to make decisions outside the object.
Why else would you want to get the state of an object?
> Any decisions based entirely upon the state of one object should be made inside the object itself.
If your classes are 50 lines long, I guarantee you that other classes will be making decisions on other objects behalf.
> Then again, they violate the Open/Closed Principle.
I think the industry is largely realizing that this is a bad principle, as it implies inheritance. I think most people outside the enterprise java world now realize that using interfaces or free functions is largely better.
Re: Want cleaner code? Use the rule of six
#128Let say you have a long code block that includes the revised snippet:
> query_params = s.split('?')[1].split('&')[-3:]
> mylist = map(lambda x: x.split('=')[1], query_params)
> ...
> ...
> (some more complex transformations, that only depends on mylist)
When you're reading the later stages of the code, you still have to maintain a memory of what "query_params" does, even though it's no longer relevant. That actually increases the burden on your working memory. The one-liner is more complex to understand initially, but it self-documents that the only info that is relevant to the downstream is the result of the map(...).
In general, the more variables that are declared in a code block, the more effort it is to understand, and the effect is probably superlinear with the number of variables. I'd say if you have to declare more than 5-6 variables, you should split into a separate function.
Re: Want cleaner code? Use the rule of six
#129I don't necessarily agree with the step of putting the code in a separate function; that often works, but just as often makes it so that the code can't be read top-to-bottom anymore which hurts readability. In this case there's, I think, a better alternative; the equivalent-ish code in Ruby for the example code here would be something like this: values = s .partition('?')[-1] .split('&') .map { |key_value| key_value.…
The basic argument is that any time you do an extract refactor you're creating a new layer of abstraction that the next reader will have to learn and understand. This can also get worse over time as the abstractions drift away from their original purpose.
The solution she provides is to be okay with a little bit of duplication, then as patterns naturally arise in the codebase you can refactor when you know a few use cases and can clearly define the concept.
[1]: https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction
Re: Want cleaner code? Use the rule of six
#130use statically typed programming languages. Favor composition over inheritance . Develop bottom-up (reusable classes) instead of large-scale up-front design. SOLID principles (SRP being the most important). The Bottom-up approach also favors Unittesting. Code reviews, clear code formatting rules (simple editor plugins do the trick). Use static code analyzers. IMHO this kind of object-oriented programming leads to NEW…