Stop Recommending Clean Code

  Рет қаралды 552,399

ThePrimeTime

ThePrimeTime

Күн бұрын

Пікірлер: 1 300
@CamembertDave
@CamembertDave Жыл бұрын
I feel like the point where clean code goes from being a positive to a negative is the point at which you start thinking of it as a set of rules which must be adhered to instead of just a sniff-test. If it looks messy, it needs cleaning; if it looks clean, it is clean.
@monkev1199
@monkev1199 Жыл бұрын
Yeah fundamentally "is this code clean" is always going to be answered with "I'll know it when I see it"
@ivanjermakov
@ivanjermakov Жыл бұрын
Love that analogy. After thousands of hours of looking through the code you can almost always immediately tell what smells and what not.
@AScribblingTurtle
@AScribblingTurtle Жыл бұрын
"Clean Code" as a concept has the flaw that it tries to encapsulate understandability, readability, and easy maintainability, which are all subjective traits, that not only influence each other but also highly depend on the programmer's coding style. So what is positive and negative depens on who looks at it. In the Video, the only thing, that `private void includeSuiteSetupPage()` adds is the information of "Page", to make clear, that the `include` in the function is including a "Page" You could have easily done that with a comment or by properly naming the freaking module/file that is included. The function makes the line more readable, yes, but harder to understand and maintain because there is now an extra function, that could possibly be used somewhere else, that could have optional parameters, that could change the instance in different ways.
@jordixboy
@jordixboy Жыл бұрын
Doesn't work. Everyone has a different understanding of what is clean.
@zeezor
@zeezor Жыл бұрын
I totally agree, the moment you sanctify clean code is when you start veering off from the positive it's meant to bring to your code.
@steveg1961
@steveg1961 Жыл бұрын
I write functions of two basic types. Most of them (the great majority) are relatively small and perform only a few (or one) specific operations. But I also write what I think of as "master" functions that can be quite lengthy, and which perform a series of oprations, which are using the smaller functions. I've done it this way for 40 years and it has served me well.
@Slashx92
@Slashx92 Жыл бұрын
I write automations and that's how I make my functions too. If there is a important step in the automation that needs emphasis, or is the representation of a defined business logic (and not just moving data around) that's a separated function, so it can have a name, and be reviewed and maintained by itself. But it will be only called by the main function Once a function called inside the main function calls more functions that are not utilities, it starts to get messy and hard to follow
@MoguMasso
@MoguMasso Жыл бұрын
I agree. Whether it's OOP or not, code written this way, in most of my cases, lead to clearly written routines which didn't need too much documentations to understand.
@dupersuper1000
@dupersuper1000 Жыл бұрын
I tend to agree with this process. As a FP guy, I prefer to think of it as “data queries” -> “data transformations/aggregations” -> “command executions”. Most systems have that basic structure. You have some data, you need to transform that data into something more immediately useful, and then once you have the data you need in the format that you need, you use that data to execute some process that has some effect on the broader system (e.g. writing to the database or displaying a UI component). It’s all effectively a data pipeline where the end of the pipeline is where you “do the thing,” so to speak.
@explosiver
@explosiver Жыл бұрын
That's basically how programs works as a whole. They have a main function that loops and runs everything else.
@steveg1961
@steveg1961 Жыл бұрын
@@explosiver I often don't do much in main except use it to call into other functions.
@sealsharp
@sealsharp Жыл бұрын
The biggest improvement to the code i write was starting to do unit tests. Because when the tests are annoying to write, it is a sign that there are structural issues.
@FlaggedStar
@FlaggedStar Жыл бұрын
Unfortunately, this falls in to the trap of over-engineering your code. Making code testable forces practices like dependency injection and keeping classes/functions small on you. Those aren't necessarily bad things, but it radically changes the structure of your code.
@ivanjermakov
@ivanjermakov Жыл бұрын
Also, tests are useful for those who want to know how the code should be used. If the unit test was difficult to write -- the unit will be difficult to use.
@recarsion
@recarsion Жыл бұрын
I must have never written good code then because I've never found writing unit tests not annoying af lol
@aoeu256
@aoeu256 Жыл бұрын
@@FlaggedStar you can have dependency injection with methods rather than needing full blown classes which is much shorter imo.
@FlaggedStar
@FlaggedStar Жыл бұрын
@@aoeu256 That's not considered good practice unless you have a damn good reason to do it. Read some Mark Seesman.
@vhaangol4785
@vhaangol4785 Жыл бұрын
Based on experience, clean code oftentimes leads to unnecessary abstraction and indirection. There are times when it makes sense to apply the techniques for writing "clean code", but applying it to almost every code is insane. It makes me think, "Are we really trying to solve a problem here or are we simply abiding by these rules because we think this is the only right way to write code?"
@airman122469
@airman122469 Жыл бұрын
I like clean code in the abstract sense. But yes, it almost always, in practice, leads to a bunch of abstractions that ultimately do not need to exist. But I can see starting with clean code, then reducing the abstractions to slim it down.
@khatdubell
@khatdubell Жыл бұрын
Neither, its called catering to the lowest common denominator. When you let people use their "best judgement", you will frequently be disappointed.
@Flackon
@Flackon Жыл бұрын
Sorry, too milquetoast. just STOP writing clean code
@orbatos
@orbatos Жыл бұрын
Like many similar ideas, treating it as some kind of hard rule is just ridiculous.
@NoX-512
@NoX-512 Жыл бұрын
​@@orbatosNot at all. Clean Code is a horror show.
@klaudyw3
@klaudyw3 Жыл бұрын
+1 for the procedural code thing. To an extent it's the embodiment of "The code should read like a narrative".
@jespergustafsson7664
@jespergustafsson7664 Жыл бұрын
True!
@dickheadrecs
@dickheadrecs Жыл бұрын
sometimes you just want to read the synopsis
@publicalias8172
@publicalias8172 Жыл бұрын
@@dickheadrecs ... so look at the summary
@GeneraluStelaru
@GeneraluStelaru Жыл бұрын
@@dickheadrecs True but not on a paragraph level.
@dickheadrecs
@dickheadrecs Жыл бұрын
@@GeneraluStelaru yeah good point. i’m going to make my code editor make the first letter of each paragraph 36pt
@dorinsuletea1928
@dorinsuletea1928 Жыл бұрын
In Clean Architecture Uncle Bob had IMO a very insightful take on DRY : “But there are different kinds of duplication. There is true duplication, in which every change to one instance necessitates the same change to every duplicate of that instance. Then there is false or accidental duplication. If two apparently duplicated sections of code evolve along different paths-if they change at different rates, and for different reasons-then they are not true duplicates. Return to them in a few years, and you’ll find that they are very different from each other.”
@stunningride6073
@stunningride6073 Жыл бұрын
Oh DRY is one of the most misunderstood principles in IT industry....
@GuusBloemsma0
@GuusBloemsma0 Жыл бұрын
It is safer to err on the side of DRY than on the side of duplication. If you have this common piece of code that you factor out and now you have to introduce a parameter to introduce a slight change for one invocation vs the other you can easily duplicate the function later and remove all the conditions. Many refactoring tools even automate that. The other way around you will see two similar functions that grow further apart while trying to do the exact same thing. You recognize it by always having to modify both pieces of code, often in separate commits because it is always forgotten. It is going to be very hard to unify them later on.
@Jabberwockybird
@Jabberwockybird 11 ай бұрын
WET is better than DRY.
@wdavid3116
@wdavid3116 Жыл бұрын
I was hugely surprised when I saw that clean code was published in 2008. I thought we knew better by then. A Philosophy of Software Design is a much much better book. My main concern with clean code is what that book terms shallow abstractions. You break down your problem to such a tiny tiny level that the code in each element (whether that's a function or procedure or method or whatever the language you're using calls it,) becomes super trivial but the sheer number of tiny basically worthless abstractions makes your code insanely complicated and hard to read or change. I remember the first time I heard someone say that a function should be no more than 4 lines of code and I couldn't understand how anyone could possibly think that was a good idea.
@theodorealenas3171
@theodorealenas3171 Жыл бұрын
It is pretty crazy, but so are techniques of high level artists and people don't question that as much. I'm trying to learn to write tiny functions, like Martin, and it seems to be a separate skill set to both read and write these. The benefits are other things, like how you can more easily avoid reading code you're not interested in.
@wdavid3116
@wdavid3116 Жыл бұрын
@@theodorealenas3171 I just straight up disagree with that. I think it's an anti-skill and if your code is well organized in properly sized functions (whatever size that ends up being,) that make sense you can more easily find the code you want because there will be a sensible number of abstractions to sort through when you're looking for it.
@madjesta
@madjesta Жыл бұрын
I've seen code that is abstracted to methods of at most 4 lines. I felt it was utter and total baren trash code that would never make sense since it would take too long to read.
@jimmyjam-vc6rf
@jimmyjam-vc6rf Жыл бұрын
Yeah some software devs try to be some purist holy man that walks in the light of the divine code quality and standards. These people usually have the worst turn around time for actual features and finished products. Most of their focus is delicately building a house of cards and obstracizing anyone they share a code base with that they must repent for their sins are many.
@davidgreetman3704
@davidgreetman3704 Жыл бұрын
I have never had a problem with changing sth that was tiny. Of course, reading it and wrapping your head around it is stupidly hard. For me, it is not about lines but about how many things that function (or whatever) does. If it is trivial, do not break it down. If even trivial things are useful because you use it many times, then make that small function. But breaking down code because it is too long is useless.
@reinoob
@reinoob Жыл бұрын
"Right click -> format code" is clean enough
@tokiomutex4148
@tokiomutex4148 Жыл бұрын
Use prettier
@sto3359
@sto3359 Жыл бұрын
🤔
@silviogames
@silviogames Жыл бұрын
IntelliJ has a "code cleanup" option
@maxharmony6994
@maxharmony6994 Жыл бұрын
mouse user detected
@ChillAutos
@ChillAutos Жыл бұрын
not formatting on save is a code smell kek
@andrewallbright
@andrewallbright Жыл бұрын
“Clean code” soon rebrands to “perfect code by perfect coders; you’re an awful programmer if you don’t do all of this and buy all the books.” Lol
@replikvltyoutube3727
@replikvltyoutube3727 Жыл бұрын
Article author: Do this, buy this book Also book authors: article author
@paulojose7568
@paulojose7568 Жыл бұрын
You guys can't even write a book and you're here hating the author who probably just wanted to help the industry in 2008 lol
@crides0
@crides0 Жыл бұрын
But it's not even perfect code. It's just perfect code from Martin's perspective
@khatdubell
@khatdubell Жыл бұрын
@@crides0 Its not even that. Its imperfect code form Martin's perspective that he is refactoring. The original code seems to come from Ward Cunningham and Rick Mugridge.
@NoX-512
@NoX-512 Жыл бұрын
​@@paulojose7568No, he just wanted to line his pockets. Clean Code is a shit show.
@Kavukamari
@Kavukamari Жыл бұрын
I'm going to start programming WET and DIRTY code and you can't stop me, in fact everyone is required to watch
@drno87
@drno87 Жыл бұрын
George Orwell wrote an essay where he gave rules for clean English. The first five were simple guidelines. The sixth was "Break any of these rules sooner than say anything outright barbarous." That last one is missing from Clean Code.
@vasiliigulevich9202
@vasiliigulevich9202 6 ай бұрын
It is not missing, Uncle Bob has introduced so many caveats over years, that no concrete thoughts from the book left.
@DoubleJumpPunch
@DoubleJumpPunch 6 ай бұрын
​@@vasiliigulevich9202Oh, so the book is"perfectly" abstracted now 😂
@jacobleslie8056
@jacobleslie8056 Жыл бұрын
Function length is easy. Your function should be the correct length. Done.
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
Love it
@chriswolf4715
@chriswolf4715 Жыл бұрын
I do try to keep my functions to the "one screen" size but I don't treat it as an absolute or anything. If it can't fit on one screen, I look for ways to make it more more succinct. If I can find some, great. If not, no harm done.
@voskresenie-
@voskresenie- 3 ай бұрын
​@@chriswolf4715 no you buy a larger screen. it's a business expense. necessary and reasonable. tax deductible. I am not a lawyer and I don't pay taxes.
@Tony-dp1rl
@Tony-dp1rl Жыл бұрын
In some parallel universe somewhere , there is a reality where OOP never happened ... it rains donuts there.
@marcusaureliusfanboy
@marcusaureliusfanboy Жыл бұрын
25:32 I feel this comes from the expectation that unit tests will target the public interfaces. Refactoring majorly would involve cleaning up the private methods used in these public-interfacing methods and thus strong unit tests can verify the correctness of the public interface after its internals are refactored.
@andydavies6522
@andydavies6522 Жыл бұрын
I had a developer on my team who used to follow clean code to the letter, and produced code that took an obscene amount of time to debug as it jumped around way too much and we couldn't keep the context in our heads. We dumped the entire codebase and re-wrote it from the ground up and was at least 10x more productive and produced fewer defects.
@blubblurb
@blubblurb Жыл бұрын
Same experience. In my case, this programmer was in charge to set the coding rules, so we all had to refactor the code to smaller and smaller functions. Way more unreadable and also way harder to debug. Also with all those arbitrary rules we started to think more about how to structure the code then on how to solve the problem.
@nkazimulojudgement3583
@nkazimulojudgement3583 Жыл бұрын
@@blubblurb damn
@kecher1
@kecher1 Жыл бұрын
Obviously, that developer didn't follow it "to the letter", because if he had used TDD properly which is an integral part of Uncle Bob's method, there would be no need to "debug" that code.
@blubblurb
@blubblurb Жыл бұрын
@@kecher1 TDD has nothing todo with no need to debug the code. If the code doesnt do what you think it should do your tests can't fix that.
@stunningride6073
@stunningride6073 Жыл бұрын
@@blubblurb If you can't understand what the code is suppossed to be doing based on the tests then your tests are shitty.
@leakyabstraction
@leakyabstraction Жыл бұрын
7:20 Careful ordering inside source files is still a great advice. The concept is simply to have the actual public interface of your component at the top, and the implementation details below it. Or, generally, ordering it from large concepts to small concepts. It's easy to see how it is totally confusing when you open a file, which has some name that represents a concept, and what you see there first are some crazy abstract stuff which is hard to connect mentally to the function of the file/component... It's just a general sane advice for decreasing the friction of work.
@jgndev
@jgndev Жыл бұрын
I worked in a “clean code” shop. The end result was you are writing very specific code that would only work in that code base.
@davethorn9423
@davethorn9423 2 ай бұрын
As long as it works what's the problem
@wesselbindt
@wesselbindt 2 ай бұрын
I mean, that's what you're paid to do
@code3129
@code3129 11 күн бұрын
​@@davethorn9423if you are just doing one thing then probably nothing. The thing is code reuse can sometimes be a bit farcical. You are almost always going to need to refactor a bit when you take similar code and apply it to something else. When this happens I find it easier and faster if the code you are taking is one or two larger functions rather than 10 or more atomized functions. Not to mention if there is a sort of master function that conducts the smaller ones that's a great starting point and can easily inform you of the dependant functions that will need to be carried over.
@TheChillBison
@TheChillBison Жыл бұрын
I still say I found Clean Code to be incredibly helpful, as I think a lot of those "basics" (or even having a discussion about them) aren't taught in school or in online courses. They either focus on the syntax of the language, or on what you're trying to get done, but not on how to code well so that other humans don't want to beat you with their keyboards. Having seen plenty of examples where code was confusing as all get out due to violating these principles, I think the important thing is for teams to have the discussions, review the code, refactor as needed, and just have something to follow rather than everyone code according to their own opinions.
@heh_boaner
@heh_boaner 2 ай бұрын
There are three types of programmers. Those who think everyone should read clean code, those who think no one should, and those who could end up contributing more than the equivalent of AI training data. Being unable to think critically about something as trivial as a book of rules makes you no better than the sum of all rules you were told to follow.
@froggy3496
@froggy3496 Жыл бұрын
Wait this guy streams during working hours?? What a mad lad
@BenRHarsh
@BenRHarsh 4 күн бұрын
That ending is the most relatable part of being a programmer. I get myself into such a singularly focused stated when trying to build something or debug something I completely forget about every other obligation.
@sb_dunk
@sb_dunk Жыл бұрын
The big problem is dogma and fundamentalism. Thinking that _this is the right way_ always ends badly. Coding principles are often good when they're treated as guidelines, and they don't always need to be adhered to.
@CaptainToadUK
@CaptainToadUK Жыл бұрын
Worse is when the dogmatism insists it is the _only_ way or removes other ways to do things because of the path chosen. Because there's always more than way to skin a cat, except when you're forced into 'the one true path' and you find that your Cat object is incompatible with the IAnimalSkinner service and so you have to spend hours extending it for that one particular case because that is the _only_ way to skin a cat in that codebase...
@brianviktor8212
@brianviktor8212 Жыл бұрын
I code since ~8 years in C#. I improved myself all alone over time. I know the patterns that are most readable and workable with. I do not adhere to any rules aside from what I think is right. DRY is something I automatically adopted for example, but I'd make an exception when it's about something that is performance critical (avoid chained method calls). I do not adhere to at least half the programming patterns because I think they are redundant. I would if they turned out to be useful at some places. The factory pattern for example... there is no use-case for what I did and do. I write a lot of universally usable code that has no dependencies, but encapsulates more or less complex logic. I found a pattern in which every .cs file can be copied out and pasted into other projects, and it will run, but the original project could also be compiled into a DLL and referenced, and also both (just in case). For me well written code and well structured project structure is of high importance unlike to my colleagues. I take everything as guidelines and apply practices as I deem best.
@carlsandsten11
@carlsandsten11 Жыл бұрын
Worse than dogma is the resistance to experience just because an engineer/developer thinks he knows best but the rest of the team gets slowed down because of it. Met too many people using the word dogma without ever thinking twice what the right architecture for the project should be and why. More than experience with people using the word than actually understanding it fully. Not saying you are. Just saying everyone I met during my decade.
@sb_dunk
@sb_dunk Жыл бұрын
@@carlsandsten11 I'm a little confused by your comment, what do you think dogma is? You say that you've met people that use the word dogma and then don't think twice about what the right architecture is, you mean they just go with "this one because it's the one we always use"? ...I would say that's dogmatic. I also don't know if I agree with your point about junior devs, if one always told me he/she was right and I was wrong, I'd get annoyed, but junior devs sure as hell can challenge my opinions and ideas, it's never slowed my team down significantly.
@schwingedeshaehers
@schwingedeshaehers Жыл бұрын
​@@brianviktor8212you know that you can have "function" that are compiled into the code, so that it don't need a function call? (At least in low level languages)
@datguy4104
@datguy4104 Жыл бұрын
When I began learning to code DRY was by far the most annoying thing that held me back. Tutorials/courses ALWAYS apply DRY in the middle of explaining something which leads to piles of abstraction and refactoring right in the middle of explaining a concept, which makes learning the concept or seeing exactly what's going on very difficult when you barely understand anything as it is.
@CottidaeSEA
@CottidaeSEA Жыл бұрын
Their lips become so DRY, they no longer KISS. They don't keep things simple and make things far too abstract, instead violating a different principle.
@Flackon
@Flackon Жыл бұрын
Yeah it's especially egregious in the context of a tutorial because it muddles up the learning experience. Even when writing code yourself for some new problem, it helps immensely to just write it dirty and make it work first, and only when you understand what's involved, refactor it
@CottidaeSEA
@CottidaeSEA Жыл бұрын
@@Flackon Not only that, but even when you refactor it, there are few reasons to split the code into so many parts. One of my primary reasons for splitting up code early is unit testing during development, but even that is kind of rare.
@theodorealenas3171
@theodorealenas3171 Жыл бұрын
It's dumb because Martin says you first write messy code and then clean it. So he disagrees with what the tutorials do there basically
@taragnor
@taragnor Жыл бұрын
I think DRY is really important. I can't count the number of times I've got weird behavior because I have two different code blocks where I do the same thing and only changed one of them, while forgetting about the other one. More often than not, doing copy/pasta code instead of DRY ends up costing me time down the road, despite the former being considerably faster initially.
@leakyabstraction
@leakyabstraction Жыл бұрын
One of the things we realized is that functions with procedural code of 100-200 lines is not that bad. It can be read linearly in a highly intuitive way, as long as it's well-structured. Yes, you can extract the chunks into small functions, but that often provides little benefit, at the cost of creating more indirections to follow, with the added risk that the function will be badly named because the developer wasn't able to find the right name for the subconcept. I think one golden rule for abstractions is that you MUST identify an actually good abstraction with an actually good name. In reasonable, non-bizarre scenarios it's always much easier and cheaper to extract/abstract later than to deal with a structure that is build on horribly unintuitive and badly selected concepts.
@g33xzi11a
@g33xzi11a 10 ай бұрын
procedural is great if you diligently use guard clauses, are mindful of placement of intermediates, precalcs, and vars, and carefully use conditionals and nesting.
@vladimirljubopytnov5193
@vladimirljubopytnov5193 7 ай бұрын
Function/method may have hundreds of lines and doing one thing (ie switch a mega enum) or be really small and do two, three things. My guide is to try to find a good, not overly general name for all what is done and if it feels wrong to read, then I split. Specifically, aAnbB(); is IMO inferior to a(); b();
@NotherPleb
@NotherPleb Жыл бұрын
I think unit tests are helpful in refactoring for one reason: I want them to break so it reminds me of what use cases and code behaviour I need to take into consideration when refactoring.
@Bliss467
@Bliss467 Жыл бұрын
A method SHOULD mutate or expose the state of the class. If it doesn’t, then why is the function inside the class in the first place!?
@davidlanda2324
@davidlanda2324 Жыл бұрын
Because this book was written for langauges such as Java where one can't write a function outside a class. Anyway metod CAN change a state, but that does not mean that you have to mutate an object. You can return a new object. Mutation can be avoided and is must have in multithreaded environment.
@rogerdinhelm4671
@rogerdinhelm4671 9 ай бұрын
Because in Java classes also act as kind-of like namespaces in C++, sometimes they are just a named scope of identifiers
@Brian-ro7st
@Brian-ro7st 9 ай бұрын
Because you can’t write anything outside a class in Java. Your framing main function is in a class. You’d think Sun would’ve realized they were being too rigid the first time they wrote a main function, but no. Same reason every Java code base ends up with abominable util “classes” which are just a collection of methods that don’t fit anywhere else.
@mfpears
@mfpears Жыл бұрын
14:40 A better rule is to create an abstraction exactly when you have a clear name for it. Removing the implementation details and replacing it with a simple description actually _improves_ your ability to understand what's going on.
@Turalcar
@Turalcar Жыл бұрын
When I don't have an otherwise strong opinion the rule of thumb I use is "does this make code shorter". If adding a function declaration ends up adding lines having the implementation copied verbatim is probably simpler.
@g3ff01
@g3ff01 Жыл бұрын
Yes. I worked with some developers that had said that they usually create a function when they see a repetition. I've never understood this. No, it's not the only purpose for creating a functions. If avoiding repetitions was the only reason for creating a function/method, they would have no name, just an id.
@evancombs5159
@evancombs5159 Жыл бұрын
@@Turalcar it shouldn't be, "does this make code shorter?" instead it should be, "does this make the code easier to understand?" Shorter is not always better with code (a common misunderstanding within the FP crowd).
@Turalcar
@Turalcar Жыл бұрын
@@evancombs5159 Hence "when I don't have an otherwise strong opinion". Out of 2 similarly legible sources I'll pick a shorter one.
@aaronhauth8880
@aaronhauth8880 Жыл бұрын
One code smell I encounter is when a function is written that says "DoThingAAndAlsoThingB()" Generally that's a code smell and means your function is doing too much. That could certainly be broken down to smaller functions
@KarlOlofsson
@KarlOlofsson Жыл бұрын
The golden rule is "Whatever you agree on in your team/project". If it works and everyone understands things it's good enough. Then you can discuss and improve from there. At least seniors and higher as junior devs can't really be expected to take responsibility for things like this, just be eager to learn.
@etodemerzel2627
@etodemerzel2627 Жыл бұрын
Queue never-ending discussions.
@RaMz00z
@RaMz00z Жыл бұрын
There's a *lot* of companies that crashes doing this my friend... Agreeing on something doesn't mean it's true...
@KarlOlofsson
@KarlOlofsson Жыл бұрын
@@RaMz00z you cant always save them
@KarlOlofsson
@KarlOlofsson Жыл бұрын
@@etodemerzel2627 unless you work alone on a hobby project there will of course always be discussions about stuff and discontent people.
@davidlanda2324
@davidlanda2324 Жыл бұрын
Always separate IO from logic. My test to prove that my program is well structured is: 1) Is it easy to write tests? 2) Are you able to easily implement a dry run or swap the CLI for the GUI? 3) Can you easily write to the console and at the same time redirect the output to another program (which makes sense only for the CLI)?
@JanMagnusson72
@JanMagnusson72 Жыл бұрын
This is also my rule of thumb. If you follow this, the code is generally easy to understand, easy to debug, easy to change and modular. It very likely also works. But it is a rule of thumb, not the law.
@anthonyparks505
@anthonyparks505 Жыл бұрын
Clean code would not be as widespread if it were not the laziest possible thing for reviewers to point out in reviews, along with whitespace nits, extra new lines whatever. Noobs and 'senior devs' alike love to pounce on this shit because they don't take the time to understand the actual point of your changes. I will sing the praises of the reviewer who finds a logic error in my code, which happens from time to time.
@etodemerzel2627
@etodemerzel2627 Жыл бұрын
Good point.
@chri5toph_k
@chri5toph_k Жыл бұрын
It's a pity you didn't go through the crazy last example of this article. I read Clean Code around three months after I had my first programming job, because a senior dev coworker recommended it to me. I wasnt so critical towards the super small functions, even though I never followed it to such extent. But when I read, how he refactored the Unit Test, I instantly thought, that I would never would do that in such a way
@JamesSmith-cm7sg
@JamesSmith-cm7sg Жыл бұрын
Months into your first programming job, and you already know better 😅
@ludovicmanga8241
@ludovicmanga8241 Жыл бұрын
​​@@JamesSmith-cm7sghahaa just though the same. Robert C Martin says at the beginning of the book that you may disagree, but respect the fact that these guys have been professional developers for so long, more than 40 years. So it is hard to match 40 years of experience with 3 months lol
@gristlelollygag
@gristlelollygag 10 ай бұрын
Is it just me, or number of years does not equate credibility? It's the merit of ideas, not length of time you spent typing code in an office@@ludovicmanga8241
@atrus3823
@atrus3823 8 ай бұрын
I’ve always hated advice like a function should do “one thing”. A function ALWAYS does “one thing.” A that thing can be broken down into other single things, but that is always the case. If it can’t be broken down anymore, it’s pretty much useless. Encapsulating multiple “things” is the point of functions.
@markaurelius61
@markaurelius61 4 ай бұрын
I don't think you get the advice. A function should be easy to understand at the call site. Having extra purposes makes it harder to understand.
@atrus3823
@atrus3823 4 ай бұрын
@@markaurelius61 oh the irony. If the advice isn't easy to understand, it's not very good advice. That's exactly why I don't like it. I get the spirit of the advice, but it doesn't say anything actionable. It's pretty obvious things should be easy to understand, but "one thing" is too vague. It's not much better than saying, "you should always write good code". Not wrong, just useless.
@markaurelius61
@markaurelius61 4 ай бұрын
@@atrus3823 Yeah, I get what you are saying, a little. I think I have internalised the idea of having functions do one thing, and to make the name say what it is. When I was a baby programmer there was the temptation to see that say 2 things were always done together so they could be put in a single function, but it was not easy to have a name or a concept that united them. But having a generic name like "InitializeData" would be unexpressive. Instead just have 2 functions called separately, say "ReadDefaults" and then "ConfigureUI". Does that make more sense?
@ShadowZero27
@ShadowZero27 2 ай бұрын
your functions only do one thing? smh
@sooja-pi9zd
@sooja-pi9zd 2 ай бұрын
The 'one thing' advice means it should do 'one thing' at a given level of abstraction. E.g. if one thing at the lowest level of abstraction might be "check there is an @ symbol in a user's email address". One thing at a higher level would be "validate the user's credentials". And then at the highest level it might be "create a user record". It's ok for "create a user record" to have multiple sub-steps inside it, because they still collectively add up to one thing. What's not good is doing more than one thing at the same approximate level of abstraction.
@mfpears
@mfpears Жыл бұрын
13:00 Totally agree. I've always hated that example. It requires so much trust in the names of the functions, and even then you can't be 100% sure _how_ they're doing why they say they're doing.
@yoshi_mel
@yoshi_mel Жыл бұрын
I've refactored that code listing to what I would do, mostly by inlining everything - it turns out it is all a single function render() that is not even 30 lines long. It's super straightforward logic, I never indented deeper than single ifs, it fits in a single scroll, and it is painfully obvious that all it does is add some test stuff around the page. The right abstraction is not a class, a method, a GoF concept, but a function.
@pilotashish
@pilotashish Жыл бұрын
flip's doing a fantastic job
@Sammysapphira
@Sammysapphira Жыл бұрын
I hate passive speech like the title of this article. "Ok but can we talk about -" "Maybe it's time to stop - "
@BurgerKingHarkinian
@BurgerKingHarkinian Жыл бұрын
I agree. It's never fails to make me cringe
@knd775
@knd775 Жыл бұрын
Oh man you’d fucking hate theo, then
@Gabriel-mf7wh
@Gabriel-mf7wh Жыл бұрын
The better title would be "Stop recommending Clean Code"
@prism223
@prism223 Жыл бұрын
It sounds like how women try to prompt sincere conversations with their virtue signaling, superficially judgmental fake friends.
@vd3598
@vd3598 Жыл бұрын
It is interesting, that Martin explains Single Responsibility Principle not as "module should do only one thing", which almost everybdy speak of. This is separation of concerns. SRP is actually "module should change by same reason". Which is really not the same as the first definition. This means that even if several code blocks looks similar and the first impulse would be to extract this similarity into single external module, but they have eventually different clients, which may require these code parts to evolve differetly, we should leave them separate. So SRP is kinda opposit to DRY and good code is somewhere in between their contradiction.
@Zikuth
@Zikuth 2 ай бұрын
Almost looks like you are screaming to abstract properly the similarity because its a class on its own, making both principles equivalent
@sburton84
@sburton84 Жыл бұрын
I knew Uncle Bob could be a bit dogmatic with his rules but I at least thought his code would be alright, but I'm actually shocked how awful those examples are. That first example would be a good example to show someone to demonstrate the meaning of the phrase "spaghetti-code".
@itellyouforfree7238
@itellyouforfree7238 Жыл бұрын
He is not a good programmer. He is not even a programmer, just a preacher. He's an incompetent wannabe going around preaching nonsense to misinformed coders.
@olafbaeyens8955
@olafbaeyens8955 Жыл бұрын
Clean code only works when you wrote it yourself. But fails when you hand it over to another team and you think that the other team that inherited your clean code is stupid because they don't understand it.
@diyanslavov7401
@diyanslavov7401 Жыл бұрын
even then it dont work
@theodorealenas3171
@theodorealenas3171 Жыл бұрын
Yes dammit. By the way I do wish one day the average skills will rise and we'll be able to write cleaner code without bothering people.
@ghosthunter0950
@ghosthunter0950 Жыл бұрын
Really? I mean clean code was originally defined as readable and easy to understand code. So you would have been wrong by definition. But I think people have really shifted this to aesthetically pleasing code instead.
@theodorealenas3171
@theodorealenas3171 Жыл бұрын
@@ghosthunter0950 it's easy to leave. You went to the wrong function and you quickly realize it's the wrong function. It's not aesthetically pleasing.
@olafbaeyens8955
@olafbaeyens8955 Жыл бұрын
@@ghosthunter0950 It looks nice, it looks readable but that does not mean that the code works as expected. In a lot of cases is obscures bugs because you assume that it is too nice to have a bug in it.
@CottidaeSEA
@CottidaeSEA Жыл бұрын
Clean code in my book is just ensuring things are properly named, the control flow is easy to read and swapping parts out if necessary is not a massive headache. I don't believe that's something which should change. Basically, overengineered solutions are not clean code and I will die defending that hill.
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
I get you have your own definition, but that's not the definition of clean code. Clean. Code is a methodology.
@CottidaeSEA
@CottidaeSEA Жыл бұрын
​@@ThePrimeTimeagen I am very aware of this. The article itself also mentions it in the beginning, that we all have our own definitions of what "good code" or "clean code" is. However, even if looking at the clean code principles, what I've said falls in line with those. The issue with what the examples given in the article is that they do not follow the KISS principle (keep it simple, stupid) that is also a clean code principle, they actively contradict the clean code principles. If you add loads of layers of abstraction through extracting functionality that doesn't need to be extracted, you're not keeping things simple. So I'd say I'm very much in line with this methodology.
@NoX-512
@NoX-512 Жыл бұрын
​@@CottidaeSEAThat is Clean Code in a nutshell. Some tried and tested rules of thumb, combined with rules that are outright ridiculous. You can't honestly tell me you are ok with that mess being recommended in CS classes.
@CottidaeSEA
@CottidaeSEA Жыл бұрын
@@NoX-512 Once you take anything too far, it stops being useful. These people take the naming and small function stuff to the extreme, which is not useful at all. As the article also explains, the given code examples also go against the very principles the one who wrote the examples promotes. That's how bad the examples are. This garbage is just bad code that violates the very principles it is supposed to promote just for the sake of keeping functions small.
@NoX-512
@NoX-512 Жыл бұрын
@@CottidaeSEA You are wrong about that. The examples are in line with Clean Code rules. Clean Code is taught in CS classes as rules to follow. I'm sure you would agree we shouldn't teach students bad habits, since bad habits can be very hard to get rid of.
@SeanJMay
@SeanJMay Жыл бұрын
So, here are some missing things, that both Pimeagen and the author missed: 0. Problem: "I have a bunch of small functions, and then I have a big function that's a mess of all of the other ones" Answer: This isn't really something that's a problem; these things can be broken down into phases. The lower the level of the library, the tighter the function should be, and the less stateful it should be. There are bootstrapping phases, and there are compositing phases in architecture; regardless of whether you're talking about FP or OO or just Imperative Proc. In FP it's the I/O code, and everything else is stateless. In an OO server, it might be a "Controller", in proc, it's whatever is close to Main; the closer to the start of the callstack, the more messy and mutative you can be, as you tie the pieces together. But you don't want your math / i/o / string / date / etc libraries to be internally stateful, or you're stuck on one thread, and in one single function invocation at a time, period. 1. Problem: "I pass in booleans when I shouldn't and something is wrong, and I don't know what" Answer: Bob actually talks about this, and the author didn't catch it? And it's good advice. A function might have a bunch of control structures to figure out what *should* be done, but then call out to another function to *do* them. That generally gets rid of the boolean passing, because the outer function decides what to do, and the correctly chosen inner function does them. 2. Problem: "How can Bob say that a function should have 0 arguments, but also no side-effects" Answer: the book is about Java, not about any other language. His point was that an object instance should return a *new* object instance, rather than mutating the old, when possible. So technically, the function has access to all internal/external class properties of that instance... it just shouldn't mutate them, if performance considerations allow for it. For procedural languages and functional languages, this is just treating data as immutable (whether or not it is actually immutable); as for the number of arguments, it goes from 0 to 1, if there is no `this`. Simple as that. His point was "ideally, it should take 1 struct and return a new value of some kind". It's just that in Java, the struct is `this`. 3. Problem: "Bob wants DRY everywhere" Answer: actually, Bob suggests pretty hard against DRY. Point being: if functions are tiny, and they do 1 thing, you can use them to do 1 thing on a bunch of stuff. Think `.map`; if it were a function called on an iterable, or a stream, or whatever, rather than a method, you could use it on a lot of things, in a lot of cases. That's his version of "DRY". In FP, that's called "Function Composition". Primagen called it "Legos". 100% same deal. He specifically warns against the typical DRY: that being big, gross kitchen-sink abstractions that need all kinds of special-case behaviors ... he already warned about how gross DRY can be when he suggested the Interface Segregation Principle and the Liskov Substitution Principle; he doesn't go back on it, here. There are others, but ehh. This is enough. I really think this author missed the crux of the book, entirely. Not to say all of it's gold... and a bunch of it isn't relevant, unless you're a Java / C# dev, specifically, and only using Java patterns that predate JDK 1.8... but a lot of the points in the book are either being intentionally misconstrued, or just obliviously missed (I presume due to lack of historical context of where the industry actually was, and what Bob is even talking about, and what problems the book was solving for). Now, none of this is to say that I'm 100% in Bob's camp. There's a bunch of good advice in the book; advice, not dogma; please don't start a religion of Bob (too late, I know). Personally, I hate the `IncludeX(); IncludeY()` nonsense. That feels like PHP to me. It also feels profoundly stateful (given they are not returns, but outputs). And thus, I find them antithetical to his point about functions. I wouldn't have a problem, however, if they were returns building properties of an object: `header = getHeader()` et cetera. When it's just i/o and no hidden state, there's no extra context to load, and no gotchas, it just does what's on the tin. That's not to say that all code can be that simple, but it is worth trying for, rather than having stateful code buried way down the callstack, and realizing that you can't have more than one network connection or thread or concurrent process at a time, because you start giving data to the wrong user.
@khatdubell
@khatdubell Жыл бұрын
18:34 This guy either actually just skipped ahead to the listing and didn't read the book, or he's being purposefully disingenuous here. This is what the book says about that code. _"the method call render(true) is just plain confusing to a poor reader. Mousing over the call and seeing render(boolean isSuite) helps a little, but not that much."_ The context of this code is BAD code that he is refactoring in the book. Its not his ideal, written from scratch, "this is how you should architect things" code example. More to the point *Its not even his code* Its publicly available java code HE IS REFACTORING.
@ShawazImam
@ShawazImam Жыл бұрын
LOL
@MrMudbill
@MrMudbill Жыл бұрын
Doesn't all code start out as procedural code, at least in part? The very idea of the main function is just that, no? So you can have 99% OOP or 99% functional, but it always starts out with that very first procedural entry point.
@Mitch_Crane
@Mitch_Crane Жыл бұрын
If I think about this too much I find myself in a philosophical crisis regarding the creation of the universe
@christiansurf1346
@christiansurf1346 2 ай бұрын
There is no procedural code. Everything is a function in OCAML, LISP F# etc. 😂
@wingedpanther73
@wingedpanther73 Жыл бұрын
I do a lot of mathematical calculations in the code I write, often statistical calculations. So I run into scenarios where it's "Validate you have all the data, if you have all the data, calculate the results of the data, then determine if the results of the data meet conditions." I COULD split that into three chunks of code, but there are a TON of variables that are getting set as part of validating the data, that then get used in calculating the results and/or in validating the conditions. That's a few hundred lines of code, but it does ONE thing, get the data into an overall result. I have other functions that are incredibly short (as little as 2 lines), but I cannot always make them short when the logic is somewhat involved.
@dmitripogosian5084
@dmitripogosian5084 4 күн бұрын
Same here, this is often a situation with scientific code that does complex calculations
@MrPoselsky
@MrPoselsky Жыл бұрын
2:24 I love one comparison which our teacher taught us. You don't want whole bread or breadcrumbs but slices of it.
@tanotive6182
@tanotive6182 Жыл бұрын
Flip just flipping off prime by leaving shit in haha 😂
@KonradGM
@KonradGM Жыл бұрын
I never understood even the distinguishing between OOP and PROCEDURAL (to some extend). Yes oop has Abstractions, inheritance etc, but in the end the code is still called in some predefined sequences. So a lot of the time, it's just calling A.function() instead of function() itself
@MichaelPohoreski
@MichaelPohoreski Жыл бұрын
You are essentially correct. Too many programmers don't understand you can write OOP in C or even Assembly Language (the game Robotron: 2084 written in 1982 did this!) There is a reason the original C++ compiler, CFront, would translate C++ into C. The difference is more about providing a *standard implementation to an API* automatically by the compiler. e.g. C++ the compiler automatically pass a hidden "this" pointer. In C you can get the exact same effect by manually passing a "self" pointer. The C++ compiler automatically generate virtual function slots. You can have virtual functions in C you just need to manually do it. C++: Bitmap.Draw( int x, int y ); C: Bitmap_Draw( Bitmap *self, int x, int y); You can tell Dennis Ritchie didn't understand the importance of providing an standard API with fseek() and fread() having the argument FILE appear in a different order. :-/ int fseek(FILE *stream, long int offset, int whence); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) fread() should of had the FILE be the first argument since you are doing something WITH a FILE object.
@etodemerzel2627
@etodemerzel2627 Жыл бұрын
I see OOP as a toolset full of very advanced tools. You can use some of these tools when you need. Unfortunately, many of the modern programmers have never learned anything else, so they tend to overuse the advanced tools as if they were just primitive building blocks.
@roboterbasteln
@roboterbasteln Жыл бұрын
C++ classes just provide the structure for stuff that belongs together and preserve object state. In C you'd have a struct (the data; POD) and some free functions to operate on the struct. In C++ you can put the data and those methods into one class. That makes it clear what belongs together and works together. Also, you can design a class in a way that it will always keep its invariants, i.e. it never produces an object in an invalid state. That's impossible to achieve with structs in C, since all fields are publicly accessible. So, most important aspect of OOP for me is encapsulation, not abstraction and certainly not inheritance. IMHO, inheritance is a much overused concept and FCoI (favor composition over inheritance) is the way to go. You ask, how is OOP different to procedural. Let me ask back, what is the difference between procedural and imperative? There is no difference. Procedural is imperative and OOP is procedural. They are contained in each other.
@TobiasSample
@TobiasSample Жыл бұрын
11:58 a function isn’t too long when it’s over a line limit, it’s too long when the code inside is getting away from the purpose of the function
@d-rex7043
@d-rex7043 Жыл бұрын
I started getting into a procedural style, under my own steam, when doing a C course in uni... but after making all these beautiful atomic functions, I then had to pass about 5 or 6 of them in as arguments to the function that would utilise them to actually do the intended task and so the argument line would end up longer that the function body! When the coordinator's 'Solution' was released, it would generally be a few chunky functions that would get a whole task done (Parse args...Do the Program... Output/Terminate) and the odd helper, simply for carrying out a sort, or something, by wrapping a library function to suit this particular program. It probably too him less time to code the entire assignment than it too me to figure out how my 'simple' functions were going to interact, on a whiteboard.
@etodemerzel2627
@etodemerzel2627 Жыл бұрын
Passing 5-6 functions as arguments? Are you sure you were doing procedural programming?
@brucemillis7111
@brucemillis7111 Жыл бұрын
Speaking to the deez nuts naming convention. I ran into an old var at work that was for Total Number of Assets for Beginning Of Year, and so now I gotta reference TotNumAssBOY for a full sprint.
@redhawk3385
@redhawk3385 Жыл бұрын
I had a teacher in college who took the clean code pill, and I was one of the few who thought it was bs the whole time.
@chetstriker
@chetstriker Жыл бұрын
Debugging an issue becomes a nightmare when people create functions inside functions inside functions. It drives me crazy when I see that
@AntiCookieMonster
@AntiCookieMonster Жыл бұрын
I bet Martin would say about needing to go into debug is a failure of clarity in code, or something like that. Funnily enough there are highly successful devs who when exploring new codebase NEVER start from reading the code instead immediately stepping through it with debugger. What tools you use definitely changes your perspective on what good structure looks like. Another example might be code completion and dependency injection not playing well together.
@Winnetou17
@Winnetou17 Жыл бұрын
Hell yeah! When I have to raise my "max open files" to 100 in my IDE just to be able to have a normal, maybe a bit complex, flow opened and having 5 "Processor.php" files ... yeah, VERY clean, I can't tell which is which, where I started, where I went, so helpful, much productiveness wow!
@aoeu256
@aoeu256 Жыл бұрын
Instead of debugging you could write tests.
@aoeu256
@aoeu256 Жыл бұрын
@@AntiCookieMonster For a code base in a dynamic language you could write introspection tools that convert every function into a logging version of a function, and then get your editor to show the logs next to the function when your editing it while the program is still running.
@chetstriker
@chetstriker Жыл бұрын
@@aoeu256 I'm talking about when I get hanging somebody else's code that I'm supposed to fix and then you have to figure out what they were doing, and how they organized stuff. Tests are usually written after somebody had it working if they even bothered. It's easy when a function encapsulates an full idea minus the parts that are going to be reused a lot, but it's a nightmare when you're trying to read code where the function just points to 30 other tiny functions with pointless descriptions or hundreds of tiny 2 lines of code functions where you have to jump everywhere to be able to read anything
@segueoyuri
@segueoyuri 10 ай бұрын
the thing about rules is that you should adhere strictly to them, until you know enough about the thing in question to know in which case it's best to break the rules
@fabricedugas1169
@fabricedugas1169 Жыл бұрын
I really enjoy watching your videos! Being still in the beginning of my programming career and trying to learn from books, I often find myself wondering what experience has taught programmers before me since these books came out. You're down to earth and can easily call bullshit. That's very entertaining 😂
@BiHMaverick
@BiHMaverick Жыл бұрын
I love how flip doesn't listen 90% of the time.
@flipmediaprod
@flipmediaprod Жыл бұрын
it ain’t much but it’s honest work
@istovall2624
@istovall2624 Жыл бұрын
I like the scene in saving private ryan where they assault the machine gun post and the sgt is saying how bout this how bout that, and the cpt says "how but you shut up"
@robmorgan1214
@robmorgan1214 Жыл бұрын
My preferred style involves using sequentially increasing numbers as variable names and raw pointer arithmetic instead of abstract algorithms or function names. I AM THE COMPILER!!!
@MrOnePieceRuffy
@MrOnePieceRuffy Жыл бұрын
Abstraction itself is already the Compilers Nightmare, because it can't predict sh*t from it, but to abstract every few lines of code into interpreted functions (a compiler would optimize them away anyways) would be the Processors Nightmare aswell, so I can't take his advice other than "create the pure Hell for your Computers" and well, no need on that, thanks. If an C-Dev who creates branchless code on a daily bases, would give me "clean code" advices, I would start to listen,. WithJava I just start laughting.
@banatibor83
@banatibor83 Жыл бұрын
Wrong approach I think. The code should be optimized for humans to read, then the compiler or preprocessor can optimize it for the machine as much as it likes, IDGAF, just do not want to read code which was optimized for the compiler.
@MrOnePieceRuffy
@MrOnePieceRuffy Жыл бұрын
But, that's my whole point on it... If you write branchless C-Code in embedded Systems on a daily basis you know THAT and WHY your code is ugly. If such a person would have advices how to write clean code, I would want to hear, what he have to say about it
@majormalfunction0071
@majormalfunction0071 Жыл бұрын
Return values vs output parameters are mostly identical at the assembly level on x64. 1st register is used for the return value (class MEMORY in the x86-64 ABI) and whichever register or memory is used for a given argument index. EDIT: It's OK to use output parameters when they're write-once, and don't need initialization.
@Glazer209
@Glazer209 Жыл бұрын
I don’t think it’s procedural vs functional, it’s procedural vs declarative. Any worthwhile high level code is going to be declarative, because it allows the procedural implementation to optimize because it’s abstracted. SQL is a great example of declarative, because you don’t tell the system “how” to get the data. You just declare the data that you want and the DB will determine how best to meet that.
@j.s.b.6299
@j.s.b.6299 Жыл бұрын
I do have this book, and I find it very useful. But I do not necessarily agree with everything in it. Overall though, I have learned quite a bit from it.
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
HOLY COW!!!! btw, ty ty ty ty for such a nice gift :)
@DinnerIsDelayed
@DinnerIsDelayed Жыл бұрын
Flip in fact, did not cut it out lmao
@JulianBG
@JulianBG 2 ай бұрын
That "thing" with the boolean parameters is easy to describe - your function is indeed doing too much, for example it "updates" in one case OR "saves" in another place. Basically you've created one big function, doing two different things and that made sense in the moment you've build that way. Most likely you had only one place where you needed to call that function, but now you need to reuse that function and call it in a different place. Adding this boolean parameters "fixed" the *issue and now you have in one case do one thing in another case do another thing. But the *issue was that you have to refactor this method and split that functionality in reusable pieces of code. So adding boolean parameter means - refactor, split and simplify. Adding boolean in 99.999% of the cases will make you loose more time in long term, instead of refactoring is stright away.
@MrShnaiderTV
@MrShnaiderTV Жыл бұрын
9:17 - It's so funny when he says "I find all of this incorrect" and then switches to his code, which follows exactly the rules from the highlighted paragraph. The difference between the thinking of Martin and the author of the article with the author of the video is that they believe that the class is read all at once. In reality, while reading, you do not fall below one or two redirects, because you want to understand "what" the method does, and not "how" it does it in all the details. Such a division into functions allows the programmer who reads the code not to waste time on pieces that he does not need and it is polite on the part of the author of the code to give him/her the opportunity to stop at the level of abstraction at which he/she needs it.
@Paralellex
@Paralellex Жыл бұрын
The problem I have with dogmatic DRY is that sometimes the same (or nearly the same) code in two different places is two different conceptual ideas that happen to have a similar implementation, for now
@offilawNoone
@offilawNoone Жыл бұрын
I'm new to coding, since this is my third career) And it always seemed to me that I'm not a very good programmer, although I like it. Like it more than anything else I've ever done. But it turns out that I independently developed exactly the same approach to clean code as you have. It's cool to realize that good programmers think the same as me.
@InfinitEELabs
@InfinitEELabs Жыл бұрын
The only "good" programmer is the one who gets the job done with acceptable tolerances, with bonus points for getting it done fast. Limits are OK as long as you're aware of them and not blindly jailing yourself into a paradigm.
@torphedo6286
@torphedo6286 Жыл бұрын
The only thing I dislike about having my 80 character boundary is that I like to have very detailed error messages. So I'll have a print statement that tells me what section of the program it came from (virtual filesystem, rendering, custom file format parsing, texture conversion, etc), the name of the function, and a detailed message. It's great when debugging, but it goes WAY past that column. For example: [VFS::SARC] SARC_openWrite(): Failed to allocate %d bytes for PHYSFS_Io return value. (The "VFS::SARC" text is printed in red to make the error stand out from the green info, yellow warnings, and blue debug messages)
@PbPomper
@PbPomper Жыл бұрын
I think most ideas and concepts from Clean Code are good general advice. Its mostly common sense. You still also need common sense to know where and when to apply them and when to "break these rules".
@khatdubell
@khatdubell Жыл бұрын
This is true for programming in general. If you can recognize the benefits of advise and when to apply and it when not to apply it, regardless of your title you’ll always be a junior developer.
@theodorealenas3171
@theodorealenas3171 Жыл бұрын
Yes, Martin has a few demonstrations of himself coding for warm up and stuff, and he's just a good programmer who says philosophies. But I wouldn't call the concepts common sense, they're eye opening to me
@g3ff01
@g3ff01 Жыл бұрын
It's common sense, because you already know this. For example washing hands after toilet or after an autopsy is common sense, but it was not before 19th century. Doctors even laughed at Ignác Semmelweis because of it.
@Bliss467
@Bliss467 Жыл бұрын
For incredibly tiny functions, are you not able to trust the naming and not need to investigate exactly what it’s doing? If you do need to figure out exactly what it’s doing you will need to navigate through many layers of abstraction, but perhaps those layers are mapped out nicely to help you find what you’re looking for faster than if the code is just linear in a single larger function. Thoughts?
@Bliss467
@Bliss467 Жыл бұрын
But yeah the example code is horrendous. Your simplification was wonderful.
@ruukinen
@ruukinen Жыл бұрын
@@Bliss467 I think the problem was that a function should just do one concept, but it absolutely needs to do at least one concept. The example function that only calls other functions was basically a wrapper for those functions which was wholly unnecessary.
@zactron1997
@zactron1997 Жыл бұрын
My rule of thumb is a function/method/class/variable/etc should exist in such a way that the intended maintainer can fully understand what it does and why. If my code needs to be maintained by less experienced devs, then I'll put more effort into atomizing concepts to move more of the code base into higher level abstractions. If my team is more experienced, then abstractions can be a little more complex. Overall, I really like the style you use and propose.
@g3ff01
@g3ff01 Жыл бұрын
Thank you!
@adriankal
@adriankal Жыл бұрын
We know how to write good code at least since 1990. How in hell someone thought figuring out everything on his own, never reading anything on the topic, writing his own idea of how to write code and call it "clean code" is beyond me. Especially when people who never knew about the book (like me for 10 years) used the "clean code" phrase to describe real good practices. Fore example the idea that function should have as many lines as reader can see at once. There was research on this and the conclusion was up to 8 lines.
@afayes
@afayes Жыл бұрын
I have used the pattern of using very small methods for some time and can shed some light on what I think. One big disadvantage is that understanding the whole implementation is a lot harder. One advantage is that, you can quickly understand how a single function works at the current level of abstraction by reading through the well named method calls. The method implementation reads like natural english rather than code. It is easier to mentally process a single verb or phrase than to read multiple lines of code. This is at the heart of this style of coding. It is about quickly understanding, with little mental processing what the current method does, at the current level of abstraction without caring about the lower levels of details. A class in an OOP language like Java will typically have a few public methods. Using this style of code means that these pubic methods will be small and orchestrate their implementation calling private methods. A developer reading a public method can quickly grasp what it does at a high level without needing to process low level implementation details unless they need to i.e during debugging. Whilst I do find this style of coding elegant it can lead to lots of small methods and also figuring out the whole implementation and what the code is doing from A to Z is a lot harder than if everything was coded in a single method.
@minastaros
@minastaros Жыл бұрын
The truth is probably in the middle. Both have pros and cons. Thinking about rather smaller functions is certainly better than rather larger ones. But making _tiny_ ones only because you can is exactly the evil you described: then they lay side by side in a class _without workflow cohesion_ , which the same code would express if it were together. As you say: quickly grasping the _overall_ functionality by only reading high-level concepts is one aspect. But sometimes you need to track down a feature (or just debug something) from top to bottom in foreign code, and that can get very very tedious with the number of levels. That's what the "as small as possible" advocates oversee: the more functions, the more levels on the call stack, which _increases_ noise on another level. The art is to balance that out: providing a level where the program structure can be understood on a high level, and likewise help those who need to dig deeper by avoiding fragmentation. (You notice that I always look from the reader's side - that's what the future writer-me will be on my own code, and all the others that might review, debug, maintain that code)
@dmitripogosian5084
@dmitripogosian5084 4 күн бұрын
It is easier to mentally process a single verb or phrase than to read multiple lines of code - for me it is opposite, but that is because I come from mathematics background and do primarily scientific programming. Reading a formula (or line of code) is easier for me that parsing english phrase
@porky1118
@porky1118 Жыл бұрын
26:05 I never do tests of random functions inside a program. I only split off useful parts of a program or write libraries, which might be useful for different programms, and only then I do unit tests of the public interfaces.
@zxuiji
@zxuiji Жыл бұрын
14:54, While I agree they went too far with their refactor I also think waiting until you've duplicated even once can be a bad thing, for example recently I was programming a custom preprocessor to run BEFORE a normal preprocessor, the loop for mapping characters to code sections grew fairly large and it became hard to keep in context what was being done where, so I created a couple of inline functions above the main function and shifted the relevant code there, with that I was more easily able to see what was being done where since I only needed to call one of them in a if statement and the other afterwards to add the actual section of code. A few re-thinks later and I had a brutally simple preprocessor that will be able to support loop, templates, types and the usual macros :) Still working on the library that will support it though as the code will be part of the library rather than the app itself, the reason for that is so I can use it on shader code also.
@Jason-xw2md
@Jason-xw2md Жыл бұрын
I think that living fast and dying hard by any rule or guideline is just limiting yourself. Imo one should take the pragmatic approach, if it makes sense to abstract something right away then do it, if it doesn't, then don't. Everyone wants to apply things unilaterally and treat these guidelines like silver bullets instead of just using them as a tool
@TurtleKwitty
@TurtleKwitty Жыл бұрын
That's the differenc betwen "This code is becoming overly complex, what are the functional units I can extract out to make it easier to reason about" vs th clean code "this if block has two statements thy must be made into a fun tion that als ocals a function that calls another function to set a single class variable". There's logical places to split up code but they never lead to anything near what "Clean Code" dictates (aka clean code =/= "Clean Code" in the slightest)
@Winnetou17
@Winnetou17 Жыл бұрын
I think the original idea was that if the only reason to refactor is because you want to avoid duplication THEN you should think that it should be used in 3 places and only then abstract it. Not that all abstractions should come from using duplications.
@capivaraalien1466
@capivaraalien1466 Жыл бұрын
About the function discussion, It's probably more effective trying to think to break functions not in how long it is, but about the properties of the function. Is the function extensible? Is the function testable? Is the function isolating a problem? Is the function easily readable? I think the decision if a function is long enough should come from the concept you are trying to implement, from it's purpose, or any other property related to it's use.
@pchasco
@pchasco Жыл бұрын
I stopped reading the book after I read his advice on functions. And I am very glad I did not read this early in my programming career.
@airman122469
@airman122469 Жыл бұрын
Yeah, the advice on functions is garbage. The architecture guidelines aren’t horrible though.
@Chiramisudo
@Chiramisudo Жыл бұрын
14:33 How do you know you're repeating yourself (or more likely, someone else) three times when the code base is millions of lines, for example? I suppose this is where AI can help us clean our code in a more sensible and less dogmatic manner. Ultimately, use good sense. I love the comment of limiting methods by concept rather than a line count. I've done that my entire career, but even that, not to the extreme. Use good sense! Unfortunately, that generally only comes with wisdom and experience. It's not easy to teach.
@espenskeys
@espenskeys Жыл бұрын
The functions in the example are not there to prevent repetition, they are there to hide the implementation of the different concepts behind an english word description of what is happening. The idea is that you do not need to know the details about how you include the setup page, you just need to know that at that point, that portion is being handled. The whole point of clean code is to write for the next developer who has to work on the code you wrote. The private, only used once private functions will be inlined by the compiler, there will not be jumps, calls or returns made.
@SianaGearz
@SianaGearz Жыл бұрын
But then you have the situation that the English description is faulty, it does not encompas exactly what the function does. It's worse than a comment. And you have broken up flow instead of through flow, so when the code does something that isn't quite what you expect it to, it takes too much extra effort to understand.
@asdqwe4427
@asdqwe4427 Жыл бұрын
Dry is only good when you are 100% sure that the code does not have to change independently of each other
@ebn__
@ebn__ Жыл бұрын
17:45 You are not crazy sir, that's the only reason for OOP to exist.
@erickmoya1401
@erickmoya1401 Жыл бұрын
Wasnt "Clean" done in a world of newbie programmers doing OOP?
@MultiProGGer
@MultiProGGer Жыл бұрын
One really bad thing that this (15:04) extreme "minifaction" and factoring of code into a bazillion small functions does, is that it communicates the wrong thing. A function - at least to me - communicates that what it does, at least in principle, is something that could be repeated. So if i find myself in a similar context as another callsite (i.e. i fulfill the same prerequisites), i can and should call the function. But something like "includeSetupPage" (in the example) can probably not be called again, because it seems to have side-effects that would cause an error if done again.
@digitalnorth
@digitalnorth Жыл бұрын
Unrealistic Code beauty standards in 2023 ? Nahhh
@racingforbreakfast6131
@racingforbreakfast6131 Жыл бұрын
I don't think most people understand what clean code really is. You all hate it because it's "harder" to read or to produce. The number 1 pain in the ass in programming is changing requirements. If you have working software without clean code principles employed, you will have a bad time changing the code once your boss comes into your room and says "Well, customers want feature x and y changed so it does z" and you're like fk, changing that would change this shit and this shit. If you codebase is hard to change for requirements, you need clean code. Anyone else claiming clean code is not important or even unit tests are not important has never written a line of code in production.
@climatechangedoesntbargain9140
@climatechangedoesntbargain9140 Жыл бұрын
The alternative to DRY is worse... Having to change code thats duplicated somewhere else, and you don't remember where or even know anymore that it is somewhere else (the norm when working with multiple people). The result is you change functionality only in one place, fix a bug only in one place. Now image you have duplicated code that again contains duplicated code -> problem gets twice as big. If you find that you dryed something wrongly, it's easy to tear it apart again (and this will happen less with time, because you will learn if something is just accidental duplication or not). The other way is less trivial. Repeating yourself three times: You repeat something -> have I already repeated this before? You need to search the code base if you repeated something AND you rely on it hasn't been refactored locally (e.g. Better variable name) and that you need to search a small enough subset of the code you are duplicating, because you don't know how muchbof the code may have already been duplicated.
@Inf1e
@Inf1e Жыл бұрын
well, no if it's a common method which can be factored out -- it will be factored out if it's not -- probably it's a different thing, and you shouldn't group that in the first place
@khatdubell
@khatdubell Жыл бұрын
@@Inf1e such an idealistic view. Take any significantly large codebase and you find find chunks of repeated code. I’ve personally been bitten by this bug enough times that before I change something I do a search on the codebase for identical code. The problem with that is that it might be identical, but not 100% identical. So a place that needs updating doesn’t get it. If you find yourself copying a block of code, you should ask yourself if you aren’t better off making it reusable. If the answer is no, you should probably notate that it’s a copy of similar code
@darylphuah
@darylphuah Жыл бұрын
​@@Inf1e my team recently spent about 6 weeks refactoring some code which had chunks copy pasted at least 3 times in different areas, I think the record was same chunk 9 times in different files. it was a bloody mess to untangle. This is what happens when you don't follow the DRY principle.
@Yay295
@Yay295 Жыл бұрын
@@darylphuah We had a collection of 16 applications all using the same common code, and all of it was duplicated. Except sometimes it had been changed to fix a problem in one of the applications, but not the others. It took me a few months to untangle that, making sure to keep all of the bug fixes from each of the applications, without breaking one of the other applications by adding that fix.
@marcusrehn6915
@marcusrehn6915 Жыл бұрын
It makes sense to have a few set ways to communicate with another service, but I see so many cases where module X is used by A, B and C, in the name of DRY. Then something changes in B, and then someone adds some more parameters and if statements to X. Let this repeat for a while and you got yourself a ball of mud. In so many cases, copy pasta makes more sense.
@enderminer206
@enderminer206 Жыл бұрын
13:25 this is literally how people write code at my company, it drives me insane
@spatialfree
@spatialfree Жыл бұрын
Clear Code > Clean Code
@bill.j.pearce
@bill.j.pearce Ай бұрын
Gosh it's so nice to see people calling out this nonsense. I've had senior developers point to this guy's books as gospel and mandating short-as-possible functions, when it literally made the code so much harder to work with and reason about, and they themselves inexplicably couldn't follow the advice. When 80% of your code is just functions calling other functions calling other functions, it can be SO hard to track down where behaviour actually lives, and then so much more painful to change it when requirements inevitably change or behaviour needs to be added.
@zxuiji
@zxuiji Жыл бұрын
23:44, I agree, with procedural you can see WHERE things start and end (with the exception of threading but going to have that problem with OOP too). Furthermore in procedural you can have your cake and eat it too, you want objects? Just make 'em and pass them as parameters, you want virtual functions? Just add callbacks to your objects or as parameters, or both even! There is 0 excuse for like OOP more than procedural, liking OOP more just screams you're incompetent at programming, pea brained or both.
@Jabberwockybird
@Jabberwockybird 11 ай бұрын
I find unit tests on a public method are useful for re-writing the internals of that method. If private methods are added or removed etc. I call that "refactoring". Prime seems to be referring specifically to refactoring on a larger scale. (Where you are re-writing multiple units). Have I mis-understood the definition of "refactor?"
@elimgarak3597
@elimgarak3597 Жыл бұрын
Clean code and, in general, most software architectural concepts, are pre-science, which is sad. With this I mean there is absolutely zero reproducible experimental evidence backing up their claim that clean code or whatever other architectural advice they give leads to goal X (be it maintainability, lower dev time, etc.) with higher probability than other ways of doing things. In other words, it is almost speculative philosophy (which is fine to do in domains where you cannot do better than that, but this isn't the case so it is absolute BS). Instead of wasting time with platonic metaphysics we could be trying to make these hypotheses testable, and submit them to rigorous experiments. We could learn a thing or two.
@jl6723
@jl6723 Жыл бұрын
But are they even testable to encompass why people want clean code? I think that we will find such tests to be very uncertain and as such not that useful simply because when we describe something as maintainability, we may well describe 20-30 different types of maintenance actions, which we have to order in important for a calculation of a score. All testing of Clean Code will likely rely on non-scientific decisions as fundamental axioms. The results will vary wildly. In such a case, it is more useful to make it a conversation of style about advantages and disadvantages that are speculative, because at least then people are encouraged to have practical experience with the subject matter to find out what works where.
@ZealForSouls
@ZealForSouls Жыл бұрын
People nowadays are so desperate to apply "scientific" approaches, so desperate for the "objectivity" that it's really unsettling Really shows how traumatizing the death of God actually is
@tacsmith
@tacsmith Жыл бұрын
​@Airo Signi, Karna Duvi ha. My mind went there as well.
@elimgarak3597
@elimgarak3597 Жыл бұрын
@@ZealForSouls by all means, practice whatever subjective pre-scientific approach you want to. Leave God and all of the other "absolutes" stay dead if you wish to. Just don't present it as something objective and impose it as an industry standard.
@tacsmith
@tacsmith Жыл бұрын
@@elimgarak3597 Objective vs subjective cannot be applied to all things. And that is his point. As an example, objectively, it would be better to kill 10k children to save 100k others. But should I present you with that choice, are you going to make the decision scientifically, putting 10k kids to death because its objectively better in the name of science? Too many people think science is the new God of reality, but 1. Its not always clear that science is actually objective) and 2. When it comes to questions of "should you ought to" science often comes up short. 3. Lastly, the scientific approach has been wrong as often as its been right. All hes saying is often times the answer doesnt require science. The two approaches arent mutually exclusive.
@soberhippie
@soberhippie Жыл бұрын
One of the things Bob Martin doesn't do in this example for some reason is split the thing into two classes, for suite and non-suite ones
@Yuri-bt4wl
@Yuri-bt4wl Жыл бұрын
Function calls take time (those precious little microseconds add up) and stack space. Too short functions means too many function calls.
@Glinkis
@Glinkis Жыл бұрын
A good compiler will automatically inline function calls.
@Yupppi
@Yupppi Жыл бұрын
I recently wrestled with a code where I had to do triple nested for loop and I tried and tried to come up with something to remove it. Just couldn't, no algorithms, no recursion. Basically it was iterating through alphabets for each iteration of alphabets and writing all combinations down. Seemed like a pretty difficult thing to remove. Trying to make it dynamic in the levels of nesting or position was quite hellish too. I hated trying to add if inside and how the line approached the 80 character limit. I never knew, until now, that I've always tried to make procedural code to manifest my head's inner ideal. It's like doing a math/physics exercise, following logically from begin to the end. If there's a sidetrack, it comes in a logical place where it is required so you always see why something is done at which point. And when it makes sense for understanding and conceptwise, perhaps ease of programming or use, use objects. Do functional style bits when they make sense, to modify something like an algorithm.
@BosonCollider
@BosonCollider Жыл бұрын
I feel that a big cause of this is that many languages in 2008 did not let you define nested functions. Many classes that were written could be replaced with a big function, that defines some variables and some inner functions that are helpers or which are procedures that do work on those variables, but never escape the function body.
@NoX-512
@NoX-512 Жыл бұрын
That’s not a big cause of it.
@marcs9451
@marcs9451 Жыл бұрын
just include a nested scope, C has that, so does C++, Java, Rust, Go, D, Odin, Zig and pretty much any real language
@vhaangol4785
@vhaangol4785 Жыл бұрын
That's just another way of producing unnecessary abstraction. Many classes can be written in a simple, procedural manner. You don't have to create these functions that return a function (e.g. in JS where it produces a lot of memory). It's just that people often become obsessed with these patterns or principles that they apply it to almost EVERY code without understanding when they are supposed to be used. In the pursuit of mastering these programming techniques, we sometimes forget that code can be written in a simpler manner.
@BosonCollider
@BosonCollider Жыл бұрын
@@vhaangol4785 No no no, I didn't mean you return them. I just meant you declare the functions and use them only there. Since sometimes you do want the same block of code to be applied several times in the same function, but it will still not ever escape the scope of that function
@ivanjermakov
@ivanjermakov Жыл бұрын
Note that in most languages nested function defenitions will cause performance overhead
@pixelfingers
@pixelfingers 4 ай бұрын
You don’t know how much I laughed when you inlined those functions and made the code easier to understand
@poseiso
@poseiso Жыл бұрын
I used to code like that... then i worked on this moderately size project and made the functions *atomic* and holy shit it was hell and yes there was a lot of unnecessary indirection and abstraction thankfully i've learned now
@JonMW
@JonMW Жыл бұрын
This doesn't need to even be a philosophical debate: code should be whatever it needs to be for it to be as easy as possible to keep working on it.
@khatdubell
@khatdubell Жыл бұрын
Tell me you've never worked on a codebase with a single, thousand lined function without telling me you've never worked on a codebase with a thousand line function. The problem with saying "be reasonable" instead of following dogmatic rules is that everyone has a different version of what is and isn't reasonable. The villain in the story never thinks they are the bad guy. When you give someone a rule to follow, they don't have to think about it.
@HrHaakon
@HrHaakon Жыл бұрын
That's a great argument for code reviews, standards, having the tough conversations and agreeing and sticking to conventions. Which is the hard part of being tech lead. But that's your job.
@NoX-512
@NoX-512 Жыл бұрын
If the rule is good, great. If the rule is garbage, you are in for a shit show.
@AshtonSnapp
@AshtonSnapp Жыл бұрын
A good litmus test to figure out if your code needs to be refactored, is if you can come back to the project, read the code, and figure out what is going on. If you can’t, your code has a readability problem and you need to refactor. How you refactor is up to you.
@ikarosouza
@ikarosouza Жыл бұрын
I worked in a company where functions 1000+ lines were almost the norm, and I gotta say, it actually makes sense for them to be that big, the business rules involved are just that complex.
@Kavukamari
@Kavukamari Жыл бұрын
When you have a very complicated concept, sometimes it can't just be expressed in like 5 lines
@khatdubell
@khatdubell Жыл бұрын
I currently work at a company where there are functions that are 1k+ lines. They aren't "just that complex", people just suck at writing quality code. Trust me, if i ever have to do work in that part of the codebase, they will be broken down into smaller, testable functions.
@dmitripogosian5084
@dmitripogosian5084 4 күн бұрын
@@khatdubell With scientific programming I have experienced, there were sometimes attempts to hire professional programmers which try to do that. Usually it ends in 'thank you, let us do it ourselves', because the result is either inefficient, or is inflexible to further experimentation
@khatdubell
@khatdubell 4 күн бұрын
@@dmitripogosian5084 Then they sound like sh!tty programmers. Just because someone does something professionally, it doesn't mean they are actually good at it. Just that they can managed to find people to pay them to do it. My entire professional career, i've met a literal handful of developers i would consider competent.
@khatdubell
@khatdubell 4 күн бұрын
@@dmitripogosian5084 Then that sounds like a $h1tty programmer. Just because someone does something as their profession, doesn't mean they are actually good at it. At least not where programming comes into play. Other professions like lawyers and EEs, doctors, etc, need to prove to the state they are competent.
@constantinegeist1854
@constantinegeist1854 9 ай бұрын
11:00 For me an indicator that a function is too big if you have to scroll to understand what it does. Otherwise, its length is OK.
10 Coding Habits To Avoid
25:53
ThePrimeTime
Рет қаралды 174 М.
Prime Reacts: The Flaws of Inheritance
29:05
ThePrimeTime
Рет қаралды 386 М.
小丑教训坏蛋 #小丑 #天使 #shorts
00:49
好人小丑
Рет қаралды 54 МЛН
Clean Code is SLOW But REQUIRED? | Prime Reacts
28:22
ThePrimeTime
Рет қаралды 330 М.
C++ Is An Absolute Blast
1:01:24
ThePrimeTime
Рет қаралды 27 М.
Odinmade Hero / Day 72.2 / Proper 3D Inclusion Tests
42:07
JamDeezCodes
Рет қаралды 100
The purest coding style, where bugs are near impossible
10:25
Coderized
Рет қаралды 1 МЛН
Python Sucks And I LOVE It | Prime Reacts
15:43
ThePrimeTime
Рет қаралды 316 М.
"Clean" Code, Horrible Performance
22:41
Molly Rocket
Рет қаралды 928 М.
Why I Quit Netflix
7:11
ThePrimeagen
Рет қаралды 526 М.
Dependency Injection | Prime Reacts
28:34
ThePrimeTime
Рет қаралды 360 М.
How Senior Programmers ACTUALLY Write Code
13:37
Thriving Technologist
Рет қаралды 1,6 МЛН
The Flaws of Inheritance
10:01
CodeAesthetic
Рет қаралды 981 М.