3 ms·
the pace of making changes grinds to crawl as codebase becomes larger and more complex. eventually the time spent trying to understand code, figure out what cha
by jakelarkin 9y ago
the pace of making changes grinds to crawl as codebase becomes larger and more complex. eventually the time spent trying to understand code, figure out what changes can be made safely and paying down tech debt outweigh the time spend making measurable improvements.
key things that help
- focusing on extensibility/abstraction in areas of code that will require ongoing changes. This is where you most need experienced and talented engineers.
- maintain testing discipline
- conservative dependency management and picking the right battles between DIY and open-source
- creating periodic blocks of time for engineers to refactor software or architecture.
- hinkley 9y agoFairly early on I worked on a project that was size constrained due to pretty severe storage restrictions on the target device. Within a year we hit a point where every feature we added required that we first make space for it by winnowing down the rest of the code. Sometimes that was making the code more sophisticated, but most of the time is was more of a Antoine de Saint-Exupéry sort of expedition. It was a constant battle but in retrospect it's some of the most rewarding work I've ever done. After that project I intuited that projects had a maximum complexity after which the wheels fall off, so to keep a project growing past that point you have to remove accidental complexity before adding new intrinsic complexity. For the limited sample size I have direct or indirect access to, this really seems to hold. And in fact someone told me that RPI teaches something very close to this in a required class for one of their Masters programs in CS. Abstractions do not fix this problem. They put it off until the next performance emergency happens. It's an avoidance tactic and kind of paints you into a corner. Ultimately you're not looking for an abstraction (I mean, it is, but so many bad things are also abstractions that I hate to use the word for this situation). You're looking to model the problems actually being solved. You're looking for the truth.
- annywhey 9y agoI like to draw a distinction between abstraction and automation as architecture ideas. Abstract stuff is "just" more abstract and adds a new concept on top of the old. Abstraction makes the coder feel all grown up and maintain the daydream: "once it's done building the features will be so much easier." Automation is the part where we say, "this is repetitive and hard to keep track of - so make the computer do it." Automation creates leverage. And sometimes you need a truly novel abstraction to automate successfully, but in most instances you only need the same old 70's era programming constructs wired up a bit differently. Which does lead to dropping one abstraction in favor of another, as you allude to. Even if you get into, "well we need to Optimize it, we can't just do the simple and straightforward thing" you can start automating the trivial, repetitive optimizations and get into the business of generating code. And that can be abstract, but it doesn't have to be - you don't have to incorporate a whole suite of compiler checks or a runtime model, the "compiler" can be a FSM that emits source code - but it'll be automated, and you can add the interface and checks to it that are most relevant to the problem, and make the output look human-readable to some degree. Edit: another benefit of this approach is that your initial coding environment truly is "implementation detail" since it's the starting point and you just add the leverage you need from that point rather than feeling obligated to use the officially branded abstractions.