DEV Community

Cover image for Preaching 'Clean Code' is Lowering the Quality of Developers

Preaching 'Clean Code' is Lowering the Quality of Developers

Jon Randy πŸŽ–οΈ on June 25, 2022

Okay - first things first... I am in no way anti clean code, and I'm not saying it is necessarily a bad thing. However... in recent years it seems...
Collapse
 
tqbit profile image
tq-bit • Edited

TL:DR

You're right, if you preach about clean code instead of thinking through proper solutions, you're off worse than getting stuff done. But that doesn't mean you should be careless about aesthetics. Code is read by people and interpreted by a machine. Nobody likes to read a badly written article, why would devs like to read badly written code? Even if they have to, don't you think it'd lower their performance more than a clean codebase?


There are a few things I find very enlightening here and some I just can't agree with.

We would actively seek to dumb down code to the point where it is more like an introductory reader for a five year old, than an elegant, nuanced work by a master author

Isn't this a good thing? The best books I've ever read were the ones I could easily digest while learning a lot (e.g. Books by Kahnemann or Carnegie). You're right with one thing - it takes time, patience and practice to write code that just works, it just doesn't stop there. If I was presented two codebases

  1. Works, but looks ugly
  2. Looks beautiful, but has tons of bugs

I'd always scrap 2 and move on with 1. Refactoring imo is more fun (and often less time consuming) than debugging.

Learning in this way will bring a much fuller understanding - resulting in much more competent, and - more importantly - creative developers.

Again, not saying being creative is a bad thing per se. But try to imagine

  • You're lead dev of a 5-person team
  • 2 fe, 2be, 1qa guys.
  • 1be dev, 1qa dev quit because they received a better job offer. Vacancies are opened to be filled within the next 3 months
  • Your customer wants a new feature by yesterday
  • Your manager wants to deploy more features faster (= optimise pipe)
  • Nothing is documented, half of the codebase knowledge is gone with be dev #2

Taking over responsibility, you'll jump into the codebase trying to grasp what's going on. You see one module by dev#2 looking like that (pseudocode to extract mandatory build steps for a database schema, based on a true story):

export function build(cmd, cd) {
  const array = [];
  let ct = 0;

  for (let k in cmd) {
    cd.forEach(item => {
      if(cmd[k].step === item.step) {
        ct = count(count)
        array.push(cmd[k].step);
      }
    })
  }
  console.log(`Built ${ct} times`)
  return array
}

function count(abc) {
  return abc +1
}
Enter fullscreen mode Exit fullscreen mode

In another universe, your other, but slightly luckier you, is confronted with the same problem. With a difference in the codebase:

type DatabaseBuildStep = {
    step: string;
    handler?: () => void;
};

type DatabaseBuildStepMap = {
    [key: string]: DatabaseBuildStep;
};

interface DatabaseBuildTraits {
  appliedSteps: number;
    build(
        availableSteps: DatabaseBuildStepMap,
        mandatorySteps: DatabaseBuildStep[]
    ): DatabaseBuildStep[];
}

export default class Database implements DatabaseBuildTraits {
    public appliedSteps: number;

    public build(availableSteps: DatabaseBuildStepMap, mandatorySteps: DatabaseBuildStep[]) {
        let buildSteps: DatabaseBuildStep[] = [];
        for (let key in availableSteps) {
            const buildStep = this.extractMandatoryStep(availableSteps[key], mandatorySteps);
      if(!!buildStep) {
        buildSteps.push(buildStep);
      }
        }
    console.log(`Applied ${this.appliedSteps} building steps`)
        return buildSteps;
    }

    private extractMandatoryStep(
        availableStep: DatabaseBuildStep,
        mandatorySteps: DatabaseBuildStep[]
    ): DatabaseBuildStep | null {
    if(mandatorySteps.includes(availableStep)) {
      this.incrementSteps();
      return availableStep;
    }
    return null
  }

  private incrementSteps() {
    this.appliedSteps ++
  }
}
Enter fullscreen mode Exit fullscreen mode

There's a few obvious differences:

  • The 2nd codepart is more than 2x as long as the first
  • The TS code is verbose and (probably) bloated
  • Both snippets are far from perfect. I mean, we have deadlines to keep after all.

What makes the second, class based approach superior to the module implementation is:

  • It follows a logical top-down order of responsibilities (one function doesn't do it all)
  • It conveys meaning by its Types and Interface traits
  • It's readable by a human
  • The TS compiler complains if returned variables looks fishy
  • It's less prone to bugs and can easily be interpreted by other devs

Both times, the code probably works. And some people might say: "What's wrong with code 1? It does the job, doesn't it?".

Sure. But be honest. Put yourself into the world of the poor lead developer who has to jump into the breach whenever shit hits the fan. Once you're confronted with the code: Which approach would you prefer - Quick & Dirty OR well thought & aesthetic?

Collapse
 
darkwiiplayer profile image
π’ŽWii πŸ³οΈβ€βš§οΈ

I'd disagree with your assertion that the second snippet is (slightly) better; it is, in my opinion, more complex in its structure, whereas the first snippet only seems more complex because of the poorly named variables and some sub-optimal choices of syntax.

This sort of problem is usually easy to clean up by just renaming the variables to what they represent (cmd β†’ commands, ct β†’ counter, etc.) and tweaking the code to use more readable syntax (for ... in β†’ for ... of, not mixing for loops with forEach for a nested loop, etc.)

Meanwhile the second snippet of code obfuscates its intention much more deeply with its program structure. A function is hidden behind a stateless class (instant red flag), trivial actions (increasing a counter) are extracted into separate subroutine, but it hides these flaws by having more descriptive variable names, so it seems "friendlier" to the reader.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

I think you may have misunderstood me somehow. In no way did I suggest being careless about aesthetics

Collapse
 
tqbit profile image
tq-bit

I wasn't so sure here, might as well be a misinterpretation from my side.

On the one hand, you mention 'elegant, nuanced work', on the other hand, to quote:

it used to be that you just had a huge tub of bricks, and you used your own ingenuity and imagination to firstly work out how all the pieces 'work' and fit together

I'd interpret this statement as a call to action for a trial and error approach. It works fine. Just in my experience, just as often it leads to the 1st scenario I described above (working, but 'ugly' code). Which still isn't a problem until the first change request hits.

Since I have an econ/business'ish background, I've got two hearts beating in my chest. Be diligent AND done in time/budget. Which is extremely hard to achieve. Uncle Bob got me with one statement though.

If you try to code fast, on the long run you'll always be slow

Thread Thread
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

Yup, really seems like we're not on the same wavelength

Collapse
 
toxicsmurf profile image
toxicsmurf

what did I just read?

Collapse
 
maddy profile image
Maddy

Interesting topic, I enjoy reading controversial articles, they help me expand how I see coding.

To me, clean code has more to do with the question "Will I be able to understand this piece of code in 6 months time?". Often, it's okay to break the rules.

The code should be understandable by the most junior dev in the team

I mostly agree with this statement. Do we write code for clarity, or to show off how much we know about a language? My philosophy is that simple is always best. I think the meaning behind that is to say that there's no need to write overly-engineered code when you can just keep it simple.

I agree with you that learning how to code takes a lifetime. There is not set period to learn "coding", it's just never-ending.

The instant gratification you mentioned (meaning, "Learn How To Code Within X Days/Week) is a business thing, in the same way people buy programs promising them to get abs within 6 weeks (it's the same logic).

Collapse
 
fjones profile image
FJones • Edited

Do we write code for clarity, or to show off how much we know about a language?

Oh, this always bugs me. No, advanced or more complex code isn't "showing off". It's brevity. It's using the language's features. There's wide gaps between "write so simple everyone understands it", "write concise code that leverages the language's tools to the fullest" and "lolcodegolf", and we should certainly aiming for a solid balance of these.

(In fact, sometimes code golf is actually the right answer, but that's a bit beside the point...)

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

It often performs better too

Collapse
 
maddy profile image
Maddy • Edited

I agree with you, a 100%. I do believe we should use the language features whenever appropriate. My concern is more with those who write over engineered code.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

Another problem is that too often 'simple' is confused with 'simplistic'

Collapse
 
justtanwa profile image
Tanwa Sripan

Good post!

...move back toward teaching people about the languages themselves, their features, and how to use them to convert your thought processes into functioning programs.

This is definitely something I also agree with. Since I started learning to code all I see is "how to become a developer in X days/weeks" and they all tell you to learn a whole language in like 1-2 weeks... I have been learning the same language for months... am I doing something wrong? πŸ˜… But my approach has always been, try to learn how things work to understand as much as possible.

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

Carry on like that. It really is the best way

Collapse
 
thomasjunkos profile image
Thomas Junkツ

I have some issues with this. Say 5 years ago I would have fully agreed with you on this topic. Clean code for me was defined:

1) does what it says without surprises (mostly surprising side-effects)
2) is easy to read for everyone fluent in the language
3) is careful with used ressources ~ "efficient"

I think so far we are on the same page.

But I changed my attitude towards (2).

The code should be understandable by the most junior dev in the team

I agree upon that is not the goal to have. But today I would say

2) is easy to read for everyone in the audience

Which is a small change, but with an interesting impact:

Say you are working with a high skilled team there is no reason to hold back some knowledge. You are fluent in x so use it up to its full potential.

If you are publishing your code for your own behalf there is no reason anyway to hold back knowledge.

But if you are working on a team where others have to read your code the mentality of "when you do not understand quality code you are a low quality developer" does help nobody it only feeds your ego. The problem is not having a low quality team but you being a blocker in the team, because you cause extra work. I changed my perspective due to an experience where I supported another senior developer getting his project out of the door. The project was overdue. I knew newer language features the other did not at the time. So it was natural for me to put my knowledge to work. But what happened? I wasn't there when my code broke and he had to fix it. Instead of fixing the code right away he was forced to learn the new language features.

Of course you could argue with educational debt on the companies side - and you would be quite right with that - but this is of no help, when you are in a hurry to to fix just a simple bug.

So: Yes, it would be easy to blame "low quality developers", but it doesn't help the team. Sometimes there is even no time or money to educate your team.

Write for your audience - and if you are the only senior then it would be better for the team you write junior level code than to foce every other developer to adapt to your level. If that feels wrong, maybe you are in the wrong team?

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

Yup, it's a fine balance... but in recent years I do feel the balance is being lost - at least in places where I've worked

Collapse
 
michaelmangial1 profile image
Michael Mangialardi

There are some good points in this article. Specifically, I agree that many new developers know how to do some things (by doing tutorials) but lack the understanding of the why.

Moreover, we need to let developers think through things for themselves.

It is a complicated problem with that no black-and-white solution will fix.

My suggestion would be that we have clear standards for junior developers to follow. Letting them go off an do their own thing won't really invoke creativity but a mess. There is a period of time where they just need to trust and absorb from others more experienced. As they mature, you can allow them to be more influential on coding standards, let them think on their own. You may even want to have a supplementary codebase, or a portion of the codebase, that it more lack to see what those developers come up with apart from the current standards.

Order and consistency in a codebase is more important than anything. However, the focus of clean code should be to the end of reducing complexity, which may or may not improve readability--often it does.

In a word, clean code almost always will provide higher code quality than no coding standards. However, that does not mean that there aren't some gaps that we have to be intentional to fill in to get the most from it.

Collapse
 
peerreynders profile image
peerreynders

41:00: "so most teams actually like the idea of normalizing in fact some of them like it too much where if you have a creative idea of doing things differently, β€œoh I don't want to rock the boat, I don't want to do my own thing here or go off the reservation”, so instead we tend to just gravitate towards the lowest common denominator on a lot of teams and that's not good…"

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

I saw an interesting, very accurate post on a similar topic today:

positech.co.uk - Code bloat has become astronomical

Collapse
 
git_revert profile image
.git • Edited

I have to be honest, by seeing this title I first thought you were talking about the clean code architecture by Uncle Bob lol.

Regardless, you are quite on point through this whole post. For example, I have recently been working on a project which tries its best to do abstraction. But through trying to make sure the project has "Clean Code" it has been over abstracted through and through such that you cannot have people comfortably settle into the project or even comfortably make changes.

Collapse
 
pierrewahlberg profile image
Pierre Vahlberg

Clean code is not about abstraction and he who promoted that in your poor codebase should indeed read uncle bobs book(s). Its about maintainability and leveling your codes intent with the amount of abstraction you possibly introduce. People are so black and whlte its scary.

The red green refactor is a good tool in clean code. Make it work, then make it read better. Then when someone else makes changes, they do the same. Code should be possible to be used in discussion, hencr hiding an ugly for loop in a function makes sense (get filtered posts function speaks better than the for loop on line 13 where we filter posts, for an example)

Other abstractions like factories, visitors and observer, these are terms that lets people talk about code like you and me can talk about cars, drivers and mechanics. We all know the meaning without having to describe how each one works in the world esch time it is mentioned.

These are, imo, the main intents of clean code. Using these methods any senior dev can use any language features as much as he wants to leverage it for performance. If he actually is good, that is ;)

Collapse
 
xinnks profile image
James Sinkala

A great read πŸ‘.

Collapse
 
leob profile image
leob • Edited

You should provide some examples, this is all a bit vague and fuzzy ...

Where I agree is that we shouldn't dumb things down to the extreme, by leaving half the features of our programming languages unused ...

Where I don't agree is that we we should strive to inject as many obscure features into our code as we can, just to make it more "terse", or to prevent our senior devs/rock stars/ninjas/code magicians from "getting bored" ...

Readability and maintainability should be number 1 - ALWAYS.

Whether you call that "clean code" or not doesn't really interest me.

So, do I agree with the jest of what you're saying here? I don't know ... I'm not sure ... and that's the "problem" I have with this article ;)

Collapse
 
eelstork profile image
Tea

"The code should be understandable by the most junior dev in the team"

  • Well, I've been saying this a few times but I never said, "hire the worse dev you can" : )) At my current job recently I just lol'd looking at a funky one liner, which totally resonated with stylistic terseness I introduced when I joined. So yea when there's potential we can raise the bottom, and where there is no potential there's no point in hiring.
Collapse
 
spo0q profile image
spO0q πŸ’πŸŽƒ • Edited

Those who preach simplicity at all costs sometimes consider what you describe as pure elitism, while it is not the case.

The code should be understandable by the most [...] dev in the team

You can cut "junior" and the same statement may look way less ridiculous if you consider "ninja" hacks, over complicated loops and other fancies that do not bring much more value or better performance.

It's quite the same with too much abstraction that ends up in a dead-end, and you have to rewrite pretty much everything six months later, which always makes me laugh as long as I don't have to dive into it 🀣.

Don't get me wrong with this comment. Complexity is part of the job and the joy ^^. I agree with most of your points but I just find complexity is quite often used inappropriately.

Collapse
 
lucaboriani profile image
Luca • Edited

Totally agree...
Everyone in this job should aim to become capable of building their own wheel(s).
Really liked the lego comparisonπŸ˜„

Collapse
 
aarone4 profile image
Aaron Reese

Since Lego moved to selling specifics rather than generics, they have become one of the most successful companies in their market; I thing that is relevant plays against your proposal; namely teaching Why without any/enough How is not going to make any money. Business today and the need for code to be written means we don't have the time to wax-on ,wax-off learn the fundamentals; we just need to get something working. Not saying it is right or good it's just reality

Collapse
 
pierrewahlberg profile image
Pierre Vahlberg

Ever heard of startups havocing due to technical debt they cant make the time to fix? Been in a few πŸ™„ most people shipping shit are consultants or bureau devs, most people discussing performance work in hardware and most people preaching style work in open source or with licensed long maintenance/evergreen software.

These perspectives are worth considering when entering a thread like this.

It is much like discussion workout routines with a sportsman, a strength athlete, a bodybuilder and a gymnast πŸ‘Œ

Collapse
 
darkwiiplayer profile image
π’ŽWii πŸ³οΈβ€βš§οΈ

Reminds me a lot of the "A rant on change" article I wrote a while ago.

Although part of me wants to be careful about labelling anything new as inferior to the way we used to do thingsβ„’, but at the same time, I see enough evidence that this is really hurting the software world that I'm inclined to think this isn't just me being a grumpy old dev (I'm not even really old tbh) and more just an actual problem that should be fixed somehow.

Collapse
 
ninofiliu profile image
Nino Filiu

Funnily enough, Uncle Bob writes in one of the first pages of the Clean Code book that what he defines as clean code is one of many schools of thought and explicitly says that its rules and preferences should NOT be regarded as absolute. Something I heard from the mouth of no clean code hardcore supporter...

Collapse
 
yaguza profile image
Yaguel

Nice post!

I myself have used some time trying to figure out what would be the best way to write β€œclean” code. And I agree that readability should not make devs with high level of expertise downgrade their code just to make anyone understand, resulting in newer devs not learning more efficient and effective approaches of how to accomplish something.

You seem like someone with a lot of experience and I would like to know if you could recommend some good books that have helped you learn to come to the level that you are at now?

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

To be honest, no books really stick out in my head as ones that really taught me a lot about programming - I've read many and have written code in many different languages from low level assembly language to super abstracted modern languages

I'm entirely self taught (starting aged 7), with most of the learning just coming through curiosity and discovery. I always treated programming kind of like Lego. I learned how all the "pieces" fit together (using some initial guidance from the BASIC manual that came with my 48K ZX Spectrum), then I just built stuff that came from my imagination, often being inspired by program listings that I would type in from magazines, or kids computer programming books that I got from the library or for birthdays/Christmas. I think all of this gave me a solid foundation to build on, and very much a 'play' type attitude to coding. I carry this through with me to this day - following paths and technologies that interest me (rather than what's cool), trying things out, pulling things apart to see how they work, and most of all... doing things in my own way - preferring to work things out for myself rather than blindly following tutorials. I've always found this to be a much better way to learn, and find that a deeper understanding of concepts is gained. I guess I've also been very fortunate to grow with all the technology - from the first real affordable home computers back in the early 80s, through to the internet age we now live in.

I will always remember the classic Usborne Computer Books - not sure I ever owned any, but I certainly borrowed them extremely frequently from the local library! πŸ™‚

Some other books that inspired me:

The Spectrum Book of Games
Ideas for Micro Users
Step by Step Programming

I guess my main advice is that - for learning - don't treat programming like an important work skill or an academic subject - enjoy it like a toy!