8 ms·
There's a difference between a super-experienced, super-senior developer "keeping their code clean" and a junior one doing the same thing. Juniors just thrash
by blowski 7y ago
There's a difference between a super-experienced, super-senior developer "keeping their code clean" and a junior one doing the same thing.
Juniors just thrash around from one design pattern to the next, never really achieving anything other than learning what doesn't work.
A much more experienced developer will have an understanding about what clean code looks and where it's necessary. They will recognise when there is a huge amount of uncertainty, for example, so spend less time writing loads of fantastic code before they've firmed up the requirements.
So it really depends on the nature of the project and who you have on your team as to whether you need to worry about 'clean code'.
- gwbas1c 7y agoI've had a few arguments with junior developers about clean code. They want to hyper-abstract everything because that's what they learned in school. Then I point out that, if they just refactor to a single method that's 20 lines, they can read it from beginning to end and it makes sense.
- sunaurus 7y agoI assume what you're arguing against is using small functions with descriptive names as documentation. If that's the case, I think the term "hyper-abstract" is a massive overstatement. In any case, I think the core issue is really how much faith you have in the proficiency of your teammates. If you can't trust the developers in your team to actually only write functions that do what they say in the name (without nasty side-effects), then I can see why not having all the logic in front of you in one giant function can be annoying - you have to jump into all the definitions and manually double check to be sure what's happening.
- neutronicus 7y agoThis sounds more like polymorphism vs switch statement
- Fr0styMatt88 7y agoWhen I read it, what I thought of as 'hyper-abstracted' is more the mistake of building a set of generic objects to then compose your functionality out of, rather than just composing your functionality out of direct function and method calls. I've been thinking about this a lot lately actually. At some level, when you create a hierarchy of classes and/or a collection of objects, you're deciding that some logic is best implemented with that set of objects and the way they talk to each other as the fundamental building block. It's very much like designing a language; you're designing the lego bricks and then putting them together to make something. The hope is of course that you're going to be able to use those lego bricks in other situations by composing them in different ways. Where I think we can go wrong is in getting stuck on the one abstraction type; particularly in this case it's falling into a mindset where the only way to compose software is by comnposing objects. Yet at some level, you're going to be composing your logic out of function calls (or what essentially look like them). You need to know at what level you're building and viewing the system. Sure, you can build a set of objects that you can then use to build some other logic that's implemented by their composition and collaboration, but sometimes maybe all you need is a method that implements this logic more directly, using function calls and their results. From far away, it's OOP with objects collaborating via messages; from up close, it's just procedural (or even functional) code with restrictions on the state it has access to. This mistake I think is embodied in a sentiment I used to pick up on a lot at the tail end of my CS education (around the time Java was really starting to come into fashion). It was a sentiment I'd describe as something like "OOP has superceded procedural programming". To which I'd always want to ask the question "but what about inside your objects?"
- celticmusic 7y agoI think it's more about recognizing that structure is like cement in that once it's laid down, it holds things in place and can be a pain to pull up and change. For this reason, it's better to prefer as little structure as you can reasonabley get away with, not more. Now, this is a nuanced view, a senior person can absolutely insist on more structure up front and avoid issues, but they'll have a good reason for doing so that doesn't involve "it's clean code". But in general, you want as little structure as you can get away with. It's a lot easier to change something that hasn't been abstracted to death with guesses about what the future is going to hold. I think part of the issue is a perspective thing. If I spend a day throwing something together and it sits for 6 months, great. I got ROI from that code. If 6 months in new requirements come in and I decide I need to rewrite it, who cares. It worked day in and day out for 6 months off a days worth of effort. Too many people view code as needing to be long lived and unchanging.
- collyw 7y agoI also think that the whole code reuse thing is pushed too hard - leading to lot of over engineering as a result. I don't think code reuse is itself a bad thing, but it can easily be overused and cause far more confusion than benefits.
- tartoran 7y agoYes, I remember working on a product at a startup that had so much code reuse that simple flow become impossibly hard to understand, with dozens of conditions in each reusable block that you'd have a hard time making heads from tails. Code reuse can be abused badly.
- barrkel 7y agoInlined code also helps make performance howlers really obvious, e.g. repeated database fetches or code that touches more data than it needs to.
- CaptArmchair 7y agoHere's another tip for juniors: Avoid Golden Hammer syndrome. Developers do deep work with a framework which ties them to a specific language and the accompanying ecosystem. So, what you see is the "not invented here" syndrome, and how already solved problems are tackled again in that specific ecosystem. Many solstices ago, I was a PHP developer. If you'd ask me to split a 2.55 Gb CSV file in several CSV files as a one-off request, I would have fiddled with a PHP script, because that was my bread and butter. Probably would have taken something like https://csv.thephpleague.com/ https://csv.thephpleague.com/ off the shelf to get the job done. Well, no, you can do exactly that in a single line with tail, head, split and cat. Since I moved away from PHP, I have come to find a new, deep respect for the already existing general purpose commands which are part of the Unix spec. And reflecting on my earlier work, I realize that I could have solved some challenges a lot quicker. Now, this is not a stab at clean code or PHP. Both are valuable tools. Rather, a big lesson for young developers is that the cleanest code out there... is the code you didn't write at all, as you leverage what's already there.
- burntsushi 7y ago> Well, no, you can do exactly that in a single line with tail, head, split and cat. You can't, because csv records may span multiple lines. So dicing them with standard tools may subtly break them. Unless you know your particular CSV data only has single line records. (I take your broader point though. It's just that CSV is a bad example, because you usually wind up needing specialized tools to deal with them. It's likely that your PHP script would actually be more correct!)
- mynegation 7y agoThank you for xsv and other things, Andrew. To GP: also - CSV headers. Still possible in one line of shell, but it is starting to get unwieldy.
- CaptArmchair 7y agoThanks for clarifying that overlooked detail. I should have mentioned another lesson for junior developers: learn to understand the structure of your data and avoid making assumptions about formatting.
- dcolkitt 7y ago> they can read it from beginning to end and it makes sense. I disagree. First 20 lines in a single block means that any single line can have interact with any other. The 19th line's behavior can be subtly influenced by what's on the first line. That means it's not just an issue of reading line-by-line. You have to keep every line in the entire code block in working memory simultaneously. The limits of human working memory is about seven or eight chunks. When functions get longer than this, they take exponentially longer to understand. 100 lines of code broken up into 25 line functions can take ten times longer to understand than 1000 lines of code broken up into well-abstracted four line functions.
- opportune 7y agoYep, wasn’t until I started working in large codebases that I realized that inheritance/don’t repeat yourself/etc. could easily become antipatterns if used too much
- brlewis 7y agoPut another way, a more experienced developer will recognize which issues will actually make future changes slower, vs issues that are just engineering aesthetics. Ultimately the goal is to get to a great product quickly, and an experienced developer keeps sight of that.
- bilekas 7y ago> Juniors just thrash around from one design pattern to the next, never really achieving anything other than learning what doesn't work. I couldn't put this into the words as well as you did, I know myself one of the turning points of realising I had become a better developer was learning from those who taught me how to identify the design patterns and how to build up requirements. Clean code is usually less important than a good structure, if you have bad deverlopers or a lot of juniors, your processes should be in place to not allow them to go too far off course. This is what really improves the development time and the maintenance. The messy code is usually localised to a small area and if a refactor is required, its much smaller.
- mumblemumble 7y agoThe enlightenment moment is when you realize that messy code that models the business domain well is far, far easier to maintain than clean code that lives in its own clean code bubble. The former can be cleaned at any time. The latter will immediately revert to a state of pandemonium on the next requirements change. This isn't the main thrust of Sandi Metz's famous "All The Little Things" talk, but it's front-and-center in the approach she takes to cleaning up the code. Half the talk - basically all the parts where she keeps mentioning, "You'll notice our complexity metrics are still getting worse even though the code is getting better" - largely consists of getting the way the software models the business domain whipped into shape. Or, to go full analogy, no number of trips to The Container Store will leave your house feeling clean and organized if half your possessions are junk that you don't need and the furniture arrangement is awful.
- raiflip 7y agoI often wonder if I have a different definition of clean code than most people. To me clean code is code that's easy to change without breaking something, and that corresponds mostly to closely modeling the business domain. Of course other things matter as well but that's a whole book.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- K0SM0S 7y agoThat's my view as well, but it's built 100% from the trenches of real-world problem solving (I self-studied all of it, no formal academia in computing beyond a few intro classes). I think it's consensual by now (at least 'round these parts) that we've gone too far with clean and patterns and being too clever for your own sake (or that of your company) and even agile (once management took the concept over and changed it to its very opposite, kinda like democracy nowadays versus the Ancient Athenian spirit if you think about it). It's all pop culture by now, see that Silicon Valley show. The most tragic, in a sense, is that the people who created those concepts, who formalized them (extreme programming, uncle Bob, etc) very clearly stated that these are not "hard rules" and cannot work as such, ever — like we say "it's a 6" or "it's a 2" by instinct, there's no science there, no genius, just practical methods. The minute it became some sort of KPI the whole essence turns sour, possibly detrimental to the mission. When you approach things this way, with this prior or meta-knowledge so to speak, you can very much apply "clean code" principles to an otherwise very domain-driven model and software architecture; in fact one could argue you're making a true mathematical model — which is really not about people and compile times but about exactitude, precision, an as-honest-as-can-be mapping of a real phenomenon. Had we built physics like we approach "great code" nowadays, we'd have much prettier formulas that approximate truth in abstraction but never quite reach it. A treat for theoreticians, a nightmare for people with real-world, industrial problems.
- mvc 7y ago> Juniors just thrash around from one design pattern to the next I contend that one of the ways a junior developer becomes a senior developer is learning about what works and what doesn't that comes from thrashing about in a codebase. They're being paid less than the senior folks so don't worry about them thrashing about (and pair with them using an open and inquisitive mindset to help them think through the consequences of their changes).
- epicgiga 7y agoThat's the problem -- the seniors should mentor them such that they don't have to thrash around. Unfortunately that type of skill is on the opposite end of the spectrum as wrangling computers.
- blowski 7y agoYou're right, and my comment probably sounded way more dismissive of juniors than I intended it to.
- dgb23 7y agoFor a junior to become a senior dev one needs to gather experience. Meaning there needs to be an investment in a error culture and a review process, maybe mentoring, pair programming, scheduled time to learn, communicate/discuss, play and learn. These are deliberate long term investments, which are based on trust, patience and growing relationships. Senior (and implicitly) maintainable, extendable clean code doesn’t just happen out of nothing.
- raverbashing 7y agoNot to mention "clean code" suffers a lot from "no true Scotsman" fallacy and it usually means "code the code reviewer likes" Not every situation requires the same level of verbosity and be structured in the same way, for example.