DEV Community


Discussion on: Most effective and simplest way to write readable code.

joshcheek profile image
Josh Cheek

They both have tradeoffs, so my default position is to be cool with either, until I have some reason to prefer one or the other. One tip for reading code that looks like the former is to read the LHS of assignments and ignore the RHS, unless you are specifically interested in it (eg in the same way a method name abstracts its body, a variable name abstracts its assignment).

girish3 profile image
Girish Budhwani Author

I wouldn't say by defining methods we are making any trade-off and at some abstraction level we need to assign some values, just that assignment shouldn't be done at high level code. I like your LHS/RHS tip :)

joshcheek profile image
Josh Cheek • Edited

There are tradeoffs for every decision :) Eg while the initialization method was ugly, all the code within it was scoped to it. Now the code is in methods, even though they are only used by a single method. So while the constructor gets more declarative, the class gets more cluttered.

I often write objects that could basically be functions, the constructor receives their arguments, and then they have a call method to do whatever it is that they do, and all other methods are private. Within that frequent pattern, I often find it useful to restrict variable setting and getting to initialize and call. This forces the integration to happen at the top, which reduces coupling. It means I only have to look in those two places to see everything that can access that variable I'm trying to debug. By pushing the assignment into other methods, I can't glance at one spot and know all the candidates. Do note that you can mitigate this by having the method initialize the object and return it, and then performing the assignment in the constructor.

Also note that the methods here are nice declarative names, but they are implicitly depending on something. I can't tell from the code sample, but it's common for one step to need the other to have been performed already, so methods allow an implicit dependency on order of invocation. Note that you can also fix this while still using methods: pass the dependencies as arguments. This also allows you, again, to see everything that accesses some variable of interest.

Basically, instance variables are like global variables, but for a much smaller globe. So, if you're not careful, your instance variables can have the same pains as global variables, and methods operate on implicit state are the primary way to do that. So, I try to keep ivar access at the top... but, that's just a heuristic, I also write code like your pre and post refactored examples :)