Ask HN: How to improve code quality while maintaining decent velocity?
Well, first we should establish what we mean by &quot;quality code&quot;. From my standpoint, both as an engineer and as a manager, quality means that the code:<p>(1) Does what it is supposed to do and nothing more;<p>(2) Is easy to read;<p>(3) Is easy to change;<p>(4) Is efficient enough.<p>Note that these points are somewhat strongly ordered. If you have to make a trade-off between &quot;maximal efficiency&quot; or &quot;can be read by the rest of the team&quot;, you choose readability, unless &quot;maximal efficiency&quot; is required to meet a customer deliverable (&quot;acceptance criteria&quot;).<p>Note the word &quot;required&quot;. As in, &quot;we have promised our customers to service requests in under 2ms, and these rather unreadable performance optimizations are the only way we can do this&quot;, not &quot;the lead programmer likes &#x27;efficient&#x27; code&quot;. That&#x27;s not to say you should be stupid about performance -- see (4), above -- but that your goal is to deliver value to the customer, not to build a technical monument to Donald Knuth.<p>That prompts the next thing we need to talk about: what do we even mean by &quot;high velocity&quot;?<p>Clearly it isn&#x27;t just writing a lot of code. Were that the case, we could measure productivity in LOC&#x2F;day. And it isn&#x27;t in always using the minimum amount of memory or smallest number of CPU cycles.<p>From a business perspective, &quot;high velocity&quot; means &quot;delivering working features to our customers as fast as possible... forever&quot;.<p>That last bit is important. You aren&#x27;t going to get one feature request, scratch that off in a frantic 48-hour marathon of caffeine and hackery, and then be done with the rest of your career.<p>New feature requests, changes to existing features, unexpected behavior that needs to be changed... these are life as a programmer. Smart programmers recognize this, and build their code to be easily changed.<p>Now, you can&#x27;t do this by trying to anticipate every future need.  Building code to support an uncertain future is where the vast majority of technical debt comes from, because 90% of the time, you&#x27;ll just be flat-out wrong, either grossly, or in sufficient detail as to render your attempt to defend against change moot.<p>Instead, you follow a set of coding practices that help you design systems and build code that can respond to future change, without having to know anything about what those future requirements might be.<p>To that end, I highly recommend Sandi Metz&#x27;s POODR[1] and 99 Bottles of OOP[2].<p>Yes, the title of the first book ends in &quot;Ruby&quot;. Ignore that part, as it&#x27;s probably the best primer I have ever seen on building code for the real world.<p>I have also found that strong TDD -- and yes, I&#x27;m lumping BDD in with this, don&#x27;t be a pedant -- has helped me to learn to write much higher-quality code over the years. Code that is fully-tested can be changed with a high degree of confidence that you haven&#x27;t broken something unintentionally, and writing tests first forces a lot of highly beneficial design choices.<p>GOOSGT[4] is a good place to get started with TDD.<p>Last but not least, recognize that all of the above are skills -- you will need to devote time, and a lot of repetition to learning them.<p>[1] <a href="https:&#x2F;&#x2F;www.poodr.com" rel="nofollow">https:&#x2F;&#x2F;www.poodr.com</a>
[2] <a href="https:&#x2F;&#x2F;www.sandimetz.com&#x2F;99bottles" rel="nofollow">https:&#x2F;&#x2F;www.sandimetz.com&#x2F;99bottles</a>
[3] <a href="http:&#x2F;&#x2F;www.growing-object-oriented-software.com" rel="nofollow">http:&#x2F;&#x2F;www.growing-object-oriented-software.com</a>