Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Clean Code is trying to operate at a layer far more important than efficiency: code maintenance. In the vast majority of cases computers are fast enough that you don't need to worry about efficiency. (part of this is any modern language provides all the common algorithms that are already highly optimized and easier to use than the writing them by hand and so the common places where you would want to worry are already efficient).

Of course error handling and debugging are part of maintenance. However there is a lot more than those two that need to be considered as well.

There is reason to hate Clean Code, but the worst adherents to the rules are still producing far better code than some of the impossible stuff that happened before. "Goto considered harmful" is one of the early steps in fixing all the bad things programmers used to do (and some still do), but you can follow the "rules" of goto considered harmful and still produce really bad code so we need more.



From personal experience, the most time consuming maintenance issues arise because of the following things:

- third party dependencies, compatibility issues, breaking changes

- code that is bloated with abstractions and indirection

- performance issues, especially when worked around via caching etc.

- bad error handling

- inconsistent data

Simpler code that can be followed and stepped through in a straight forward manner avoids 3/5 of these from the get go. Patterns and abstractions that emerge over time are sometimes beneficial. Legacy code or third party code that overuses abstractions is really more of a hindrance and significantly slows down how fast I can understand, own and fix things.


IME the most time consuming maintenance issues are due to inconsistent code, which is usually a result of trying to avoid "abstractions and indirection" and keep it straightforward. A bunch of classes that just call each other is annoying, but trying to solve that by inlining the code results in something worse.


I agree. But here are other ways of accretion of code inconsistencies:

- Premature abstractions that are subsequently worked around around the edges.

- Automation built on top of wishful thinking instead of how people actually prefer to work.

- Inconsistent naming and file structure.

- Adopting many advanced or hyperspecific styles and techniques instead of leaning on more basic ones that already solve a problem.

I find it way easier, to go from more primitive, consistent, "inlined" code to more sophisticated abstractions that clearly solve emergent problems at a later point in time, than changing the direction of already factored, high level code.

To me it's a matter of mental capacity and friction as well. This stuff is hard, time consuming and requires deliberate effort. I rather accept that code goes through different phases of maturity and that using and maintaining the actual programs over time, gives me a much clearer path forward than applying patterns and principles in advance on an abstract level.

A caveat here is that many of these inconsistency factors come from adopting third party dependencies. In my experience this is the largest chunk of liability or tech debt.

---

However, a large factor that is often overlooked in these discussions, is also organizational scale. When you have to own and understand things from A-Z you can get away with different things than if you are one part of a much larger team and vice versa.

I'm firmly in the former category, so I have to optimize for being able to take a much larger slice of responsibility. But I can also get away with leaving code in a more raw state for longer. I assume this balance looks different the more people you add to a project or organization.

I think we need to take this into consideration in these public discussions. It's ultimately a trade off and programmers from different backgrounds will have different sensibilities.


> I find it way easier, to go from more primitive, consistent, "inlined" code to more sophisticated abstractions that clearly solve emergent problems at a later point in time, than changing the direction of already factored, high level code.

Depends. If you reach the codebase at the point where it's already accumulated subtle differences between codepaths that should be the same, that's far harder than inlining and rearranging something that's been factored badly, IME.

> A caveat here is that many of these inconsistency factors come from adopting third party dependencies.

I find the exact opposite. Developing too much internally creates a lot of inconsistency. If you hit an incompatible change in a third party dependency, odds are a lot of other people have hit the same thing and can tell you what to do.


It sounds like you have been lucky enough to avoid some of the worst code practices of history. Good for you.

I hope you can come up with a good answer to fix the problems you cite. I haven't seen anything I have confidence in.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: