6 ms·
The trick really boils down to: be messy, but clean up. If you don't do the second half of each thing (copy and paste / don't copy and paste), then you end up w
by netghost 11y ago
The trick really boils down to: be messy, but clean up.
If you don't do the second half of each thing (copy and paste / don't copy and paste), then you end up with that unmaintainable mess. If you do the second part too early, you end up with the wrong abstraction.
Sandi Metz also talks about this:
http://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction http://www.sandimetz.com/blog/2016/1/20/the-wrong-abstractio...
- dhimes 11y agoYes. It is an iterative process, like writing a story.
- manyxcxi 11y agoYes yes yes. When I'm coaching junior developers (or developers that like over engineering) this is what I try hammering home more than anything. If you looked at my code at 10-70% solution complete you'd find so many egregious DRY errors, magic values (likely with a comment above for my own memory), functions that are too long, and a whol ball of mess. If you looked at it 90-100% complete it would be nearly unrecognizable in writing style to what you saw earlier. Figure out how to solve the problem first, spend all your efforts on that, then figure out how to clean up your code and make things nice/performant/secure/etc. I've found that as I've gotten better my sloppy is better than a lot of people's clean, which means I'm spending less time on cleanliness, and getting done faster.
- JoeAltmaier 11y agoWhen I teach teenagers I tell them, there's never time to do it right OR to do it again. Time is money; Engineers are paid to solve the problem and not make a beautiful thing. Get used to just-in-time solutions and just-good-enough implementations. With that in mind, its important to have some discipline, to make your 'just good enough' not too crappy. That's the difference between an apprentice and an expert.
- Flip-per 11y agoI do not like this approach, and I think it is not the right way for medium to large software projects. Maintaining lots of interacting 'just-good-enough' code is a nightmare - and it can easily cost you way more than you saved writing it. People get lazy and sloppy early enough. I would try to encourage teenagers to go for the best and most beautiful solution that they can possibly find.
- phamilton 11y agoI don't believe this is actually measurable. Any claims about time saved or lost are merely guesses, especially in aggregate for a large project.
- dannypgh 11y agoI'm not sure I object to just-good-enough solutions, but, there's still an awfully large benefit from paying down technical debt, and I hope your students appreciate that. My approach is to pay down the technical debt before starting the next big change. I consider it akin to prepping my work site. As an example: consider a project where you're modifying some large continuously running system in production, creating an alternate codepath to ultimately replace some legacy codepath. You'll likely add the new codepath first and then migrate some subset of users to it. There might be some diminishing returns from migrating a long tail of users to the new codepath (perhaps they were better served by the legacy codepath for reasons that don't quite justify the maintenance of both codepaths). And even when they're migrated, you quite likely don't need to rip out the legacy codepath. So at some point, perhaps before all the users are on the new path and perhaps before you rip out the legacy codepath, you'll consider the project a success and move on. To me, that's quite reasonable. But consider then that any project on the same codebase in the future has to account for both of these potential codepaths. That adds an expense to every future change you make, as you have to maintain and support twice as many things. In my experience paying down that debt will pay for itself over the course of an astonishingly few (but greater than zero) number of future changes. I mention greater than zero because quite a lot of systems get decommissioned, for one reason or another. If someone is going to bulk delete your code and everything near it, it doesn't really matter how the code smell was right before: the code that smells the least is the code that doesn't exist. This is why I make various forms of cleaning up code - in-depth refactoring, deleting all unused code and tests, etc. - not the last thing I do when I finish a project, but rather the first thing I do when I start the next project. It's also much easier to explain why you're doing it to outside observers at that point - you're doing it not just because it "improves code smell" you're doing it because it makes what you're trying to do now substantially easier. The only time I think this can start to fail is if you aren't the person who would be doing the next project / you could do the code cleanup far more efficiently than the person who is doing the next project. In which case this all becomes much more hard, and you should just remember to treat others as you'd wish to be treated. But I'm not sure it totally doesn't work -- for the person inheriting your work, getting to do some amount of refactoring and cleanup may well end up being a decent way of them getting to know the codebase better (if they knew it as well as you they could clean it up just the same).
- lostcolony 11y agoIn Erlang and OTP in Action, Joe Armstrong is quoted as saying (and I'm paraphrasing here 'cause I don't have the book in front of me) - "First, make it correct. Then, make it beautiful. Then, if you need to, make it performant. Because 9 times out of 10, making it beautiful also makes it performant enough."
- neilellis 11y agoFunny I have a saying which is very similar: "Make it work, Make it work well, Make it work fast" I would disagree with beauty == performance, most performance problems I have found to be in the last place I would think them to be :-) On one (moderately large) system it was a hashcode() calculation ;-)
- lostcolony 11y ago'Place I think it to be' is completely orthogonal to beautiful code. :P From my own experience, many, many times, definitely a majority of them, when I have had performance issues, and finally found the bottleneck, and fixed it, my code was more beautiful afterwards. Algorithms were simplified, duplicated effort was removed, etc. One major one in my mind was where code was attempted to be reused, but in doing so it caused an O(n^2) behavior, where an O(n) could have been done instead. Upon finding it, and refactoring it, the code had fewer interdependencies, the logic was far more straightforward, both things I find to make for 'beautiful' code, and it ran far, far faster (from 'this particular operation takes an hour' to 'this particular operation takes < 1 second'). Had I invested time up front after making it work to clean up the code (rather than stop at 'it works, good enough') I would have stumbled upon the same fix, even before seeing the performance issue.
- rakoo 11y agoI believe the common idiom is Make it work Make it right Make it fast http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast
- lostcolony 11y ago
- codazoda 11y agoIn the real world, at least mine, once it works you get pressure to move on. Both my own mind saying, it works so it's good enough, and external pressure from a stake holder who says it looks good lets move on. I don't feel like I get to that latter 20% - 30%. As such, I try to be thoughtful on my design, but I also realize the need to get stuff done. It's a balancing act.
- BurningFrog 11y agoThe pressure you put on yourself is your responsibility. Don't pretend it's something you have no power over. The stake holder should be your customer, not your boss. Even if that dynamic is broken, you don't need to tell them it's shippable until you're happy with the code.
- chairleader 11y agoTrue, we are the ones responsible for our integrity and we often live with our mistakes, paying for poor design choices during later maintenance cycles. Just be aware that it can be easy to get lost in a yak-shaving exercise doing your cleanup refactoring. I recommend timeboxing this phase to no more than an hour, or prioritizing one or two specific tasks so that you don't go off the deep end. Don't forget that others are depending on you to get their work done. There may be a 2-hour cleanup task somewhere else in the code that will help your teammates far more than the itch you want to scratch here and now.
- sheepmullet 11y ago> I recommend timeboxing this phase to no more than an hour, or prioritizing one or two specific tasks so that you don't go off the deep end. When I read comments like this I think to myself "How can they possibly be so productive that refactoring can be done inside of an hour?". Then I remember that some developers split up projects/problems into really small components and can complete a feature or two in a single day. Well then an hour is actually a fair bit of time to spend refactoring.
- BurningFrog 11y ago
- pmuk 11y ago"Figure out how to solve the problem first, spend all your efforts on that, then figure out how to clean up your code and make things nice/performant/secure/etc." I think this explains it neatly.
- Ronsenshi 11y agoI suppose I'm similar to the way you write code. However I'd like to note that this 10%-70% in my case (and may be true for you) is applied only in cases when I'm implementing something very unfamiliar to me. If I'm working on some familiar problem or in a familiar area I tend to write nice, clean code from the beginning. As I have more and more experience in various areas it reduces number of times when I have to do this process of dirty code->refactor.
- manyxcxi 11y agoThat's definitely true for me. If I'm writing a traditional web app using a language or framework I'm very familiar with then there the difference between 10% and 100% in cleanliness is nearly negligible. But those aren't the interesting projects. When I look at my code and it looks like shit and I've got notes and commented out blocks I feel happy because I'm working on something that my brain can't just spit out a complete answer for. It also feels even nicer to be near the end and see how nice it all looks once my thoughts have formed into a solution.
- vmorgulis 11y agoSomeone should invent "immutable programming". A paradigm where you can't delete code. It's a bit the opposite of Vigil, a programming language who punishes functions throwing errors. https://github.com/munificent/vigil https://github.com/munificent/vigil