96

How to Learn/Practice Clean Code, particularly by oneself?

Profile picture
Data Engineer at Financial Company2 years ago

I'm sure Alex and Rahul talk about this in their Masterclass "How To Write Better Code Faster as a Software Engineer", but wondering how to write clean code, particularly in the context of someone who doesn't have technical people available to review my pull requests in my work or in side-projects.

I'm sure this skill is almost entirely developed by working with talented people and writing a lot of code, but is there a place for resources like "Clean Code" the book or courses on Udemy?

9.3K
5

Discussion

(5 comments)
  • 85
    Profile picture
    Tech Lead @ Robinhood, Meta, Course Hero
    2 years ago

    How To Get Better At Code Quality In Isolation

    I know I just dumped out a bunch of very abstract, wishy-washy stuff, so I'll actually answer the question now 😛

    There's 2 big strategies that come to mind for me:

    1. Open-source
    2. Side projects

    Open Source

    • This is the most "obvious" one as it literally is a way to get very high-quality engineers to review your code.
    • However, open-source is not easy, especially if you're targeting the most well-known repos to get the feedback of the best engineers. I know every few software engineers with major open-source contributions, especially junior engineers.
    • If you're going down this route, be prepared to spend a lot of time reading through and messing around with code before you're actually able to do anything (i.e. submit a substantial pull request that will get you feedback teaching you clean code principles).
    • For more tactics regarding open source, check out my latest response in this discussion about building a strong portfolio for prestigious Big Tech companies like FAANG.

    Side Projects

    • The revelation here is realizing that the version of you in the present and the version of you in the future are effectively 2 different people. This means that you can give feedback to yourself by going through code you have written in the past.
    • You trigger the self-learning phenomenon by building side projects and consistently improving them over time. This is where 99.5% of engineers mess up with side projects. They either never ship anything or ship a v1, brag about it on LinkedIn, and never touch it again.
    • When you build something and treat it like an actual product, making it a little better week after week, everything comes together. Your software has a much higher chance of attracting real users, and the flywheel begins. For our example, let's say you're building an app:
      • These users hit some weird UI bugs. Now you have to fix them and confront how hard your code is to debug. You give several methods clearer names and add logging so the code is easier to step through.
      • Now people are running into crashes. You sift through crash logs and start thinking more carefully about null safety going forward.
      • People start demanding features. You look at your code and realize that it's a complete mess to extend. There's hard-coded constants everywhere and massive god classes. You break up the god classes into flexible modules that use clear interfaces to communicate.
      • It turns out that the buttons in your app are too small and hard to click. You groan as "past you" chose to copy-paste the same button code 50 times. Instead of making the same change 50 times, you move the attributes into a common style that you can then apply to every button at once. You update the new style to make the buttons bigger, and you're good to go!
    • Even when you have 0 users on the side project in the beginning, you can still do everything I mentioned above. Make that user you! Dogfood your own app and find problems. You should be building side projects you would use yourself anyways.
    • You also don't need ultra-experienced "rockstar" engineers to look over your code to learn about code quality. If you have a buddy you can trust, pair up with them on your side project. Review each other's code and see how easily they're able to understand and extend yours.

    Writing better code is fundamentally about removing pain, whether it's pain for the user or pain for the engineer as they strive to deliver value to the user. And at the end of the day, it is very easy to generate pain with software (hopefully unintentionally of course, haha). You just have to build stuff and actually care about it.

  • 72
    Profile picture
    Tech Lead @ Robinhood, Meta, Course Hero
    2 years ago

    This is a great question! I have a lot of thoughts here, so I'll split them up into 3 separate responses:

    1. What "Clean Code" actually is
    2. How "Clean Code" can be bad code
    3. How to get better at code quality in isolation

    What Clean Code Actually Is

    I'm sure this skill is almost entirely developed by working with talented people and writing a lot of code...

    You're 100% correct! Unfortunately, this makes it pretty tricky to learn how to write good code by yourself. Code quality is something you improve at through a mix of institutional knowledge and communal effort.

    ...but is there a place for resources like "Clean Code" the book or courses on Udemy?

    This is the really hard part about learning what good code looks like - There's no concrete definition. Good code is more about the fundamentals rather than the code itself. To clarify, here's an example.

    Let's say you're working at some tech company with thorough code review, and you put out a pull request. You get the following feedback:

    "There is too much code in this 1 class - It's over 500 lines! Please abstract some of the logic outside of it into different classes to shrink it down to 250 lines or less."

    Let's ignore how prescriptive the 250 lines thing is and focus on what you, as the software engineer looking to learn what clean code looks like, should take away from this interaction.

    • Bad learning: "Writing good code means that every class should be 250 lines of code or less."
    • Good learning: "I should be wary of creating massive god classes as they hurt readability and maintainability."

    Let's unpack this:

    • The former often looks very appealing to more junior engineers as they want something very concrete. However, that's a bad takeaway as it's dogma, which is almost always bad in software engineering.
    • The latter is the healthier way of learning as it focuses on the principles of readability and maintainability as opposed to the clear-cut tactics. The end result is that you start thinking through the questions of "How quickly can new engineers grok my code?" and "If a bug appears in this code, how easy will it be for people to quickly pinpoint which line is broken?" when you write code in the future.
    • Building truly beautiful software is all about absorbing the context and respecting the nuance. This is why it's hard to find universal truths about clean code.
    • This is why Rahul and I were very careful talking about clean code concepts in this masterclass, only choosing high-level, broad-strokes principles that are fairly agreed upon. Even with the concepts we covered, I'm sure there's some obscure, weird cases where it's false.
    • Once you start talking about concrete tactics like "It's better to early return instead of doing if-else", there's going to be tons of exceptions where the idea doesn't hold up.
  • 68
    Profile picture
    Tech Lead/Manager at Meta, Pinterest, Kosei
    2 years ago

    You're right that the best way to develop this skill is to actually write lots of code with talented people around you.

    If you don't have technical people to review your PRs in work or side projects, an alternative is to contribute to open source. That's the beauty of software -- if you put in the time/effort, you can find great people to work with pretty easily! One open source project that comes to mind (and one we use for Taro analytics) is PostHog. They have tons of repos and I'm sure you could find something to contribute to.

    I don't have any recommendations off the top of my head for books/courses. I'd probably start with looking at respected developers in the field and following their blog posts or code contributions.

  • 60
    Profile picture
    Tech Lead @ Robinhood, Meta, Course Hero, PayPal
    2 years ago

    How "Clean Code" Can Be Bad Code

    I talk about this concept in our video about "doing the simple thing first", but I wanted to provide a concrete example to make things clearer. As I mentioned in my earlier response, clean code is all about the nuance. This means that code which is legitimately high-quality in one company's codebase can be terrible in another's.

    I remember there was this earlier-in-career Android engineer at Instagram who was really swept up in "clean code". For context, the Instagram Android codebase is famously simple, almost primitive. Anyways, this is what that engineer did:

    • They were tasked with adding a new screen to the app, so their code would be pretty standalone. This emboldened them try out the "new stuff".
    • They submitted a pull request with all the latest stuff (for the time) in Android. MVVM, RxJava, Retrofit, you name it.
    • In a lot of codebases, their code would have been great. There are a lot of startups who pride themselves in using the latest tech, so this code would have fit in just fine there.
    • However, this code was actually terrible. Again, this is because all code exists within a certain context.
    • The code wasn't consistent with the rest of the codebase, making it harder to read. In general, modern abstractions tend to make code sleeker and more compact while sacrificing understandability and ease of debugging, particularly with junior and onboarding engineers.
    • The most egregious problem was that this code added several new libraries to the Instagram Android app, which increased its binary size. These libraries are small for most companies (only a couple hundred kilobytes), but when you have an app the scale of Instagram with millions of users in low-bandwidth regions, this is really bad. A few hundred kB added to the app size can discourage millions of users from upgrading or even installing the app. This means that this "clean code" using all the "modern" technology would actively cause massive amounts of user harm. This is a big reason why Instagram Android has kept its codebase so bare-bones - It legitimately makes the user experience better.

    This is why I have generally been disappointed with resources I find online about how to write "clean code". They're often too prescriptive, missing the point of what clean code actually is. They'll recommend certain modern frameworks (e.g. "This new library is the best way to build a Node.js REST API") or dogmatic tactics (e.g. "All code needs 100% automated test coverage").

    At the end of the day, your goal is to make your code not suck, which I talk about in-depth here. This will look and feel different to everyone, but the important thing is championing this mentality.

  • 19
    Profile picture
    Data Engineer [OP]
    Financial Company
    2 years ago

    Thank you for such an incredibly detailed response, Alex!