5 ms·
It is incredibly important to avoid putting tag-firebreaks in the code base — anything that stops a new developer from being able to navigate from symbol to def
by gorgoiler 4y ago
It is incredibly important to avoid putting tag-firebreaks in the code base — anything that stops a new developer from being able to navigate from symbol to definition, or from definition to all uses of that function.
A couple of examples:
ACTIONS = {
“swim”: Swimmer,
“skate”: Skater,
}
# …pages of code…
def f(action, *args):
…
mod = ACTIONS[action]
mod(*args).do()
At face value, this pattern doesn’t do anything particularly wrong but anyone who arrives at f on their code safari won’t see any symbols for either Swimmer or Skater. It breaks their flow the same way switching languages might do. Sure, ACTIONS is only a hop away, but that’s a level of indirection that could have been avoided. Even worse, what if the class name was derived from a string?
The fact that the action implementations are chosen at runtime also makes life a bit awkward but the primary issue is not being able to immediately see the action classes and jump to their implementations.
Another one is calling shell scripts. We all have projects, I’m sure, where we have to shell out to some common legacy tool:
def f():
run(“legacy.sh”)
def g():
run(“legacy.sh”)
Wrapping the script in a native function does wonders for making it easier to find, especially for the poor, sacred soul who deprecates it from the codebase one day:
def f():
run_legacy()
def g():
run_legacy()
# …pages of code…
def run_legacy():
run(“legacy.sh”)
Any unfriendly pattern that breaks tag-hopping / IDE-integration is yet another small chafing of your colleagues‘ productivity. Think twice before you introduce that YAML file which defines behavior, instead of implementing it natively — your friends (and their jump-to-definition muscle memories) will thank you.
- worik 4y agoReally good. Think about the programmer reading this at write time. How to write large code bases that can be understood, every bit as important as knowing how to read them
- Denzel 4y agoSoftware Engineering at Google has lots of valuable advice and best practices to accomplish this - https://abseil.io/resources/swe-book/html/toc.html https://abseil.io/resources/swe-book/html/toc.html
- guntherhermann 4y agoI agree, when learning new codebases, the ones that take me the longest time to learn are the ones with many layers of indirection. I view over-indirection as an anti-pattern and I often see it come from engineers who take the DRY philosophy as dogma. I have seen countless cases of your second example throughout my time programming, and I'm convinced it comes from the DRY mantra that first-year CS students get drilled into their brains.
- afarrell 4y agoDRY is the easiest rule to tell if you are following, so it is one that people are inclined to follow.
- arkh 4y agoBest example of "good practice" becoming a hassle: the "interface for everything" habit. Even when the majority of those interfaces have only one implementation.
- JamesonNetworks 4y agoI can't stand this. I once worked on a project where there were seven layers of interfaces that all led down to a wrapper around a library and each step was just adding another parameter onto the call in the library. The entire PROJECT didn't need to exist, the owning project could have easily just called the library directly as it already had all the context, maybe with one method to abstract in case we needed to swap the underlying library. I remember thinking I was a bad developer for not "getting it," but armed with 10 more years of experience I've realized it wasn't me.
- patrickthebold 4y agoI've come around on this one. I (now) like having a separate interface, having just method signatures separated out makes it easy to get an overview of the class. It also makes it a bit easier to agree on the interface.
- yCombLinks 4y ago
- wilburm 4y agoomg yes. This is my single biggest complaint about large Python projects, or anything with complex implicit type conversions. Fun to write, a nightmare to read.
- tengbretson 4y agoEspecially in languages with string literal types! There's no excuse not to just have the thing be the thing when the type system can do the heavy lifting of preventing typos.