The Best Ways To Simplify Your Code? (dice.com)
Nerval's Lobster writes: Technical debt arises for many reasons—whether moving goal posts, pressure to get code tested and released, high programmer turnover, and lack of documentation. Over time, it can also render code a spaghetti-like mess. But how to deal with it? In a new column on Dice, developer David Bolton offers some suggestions, ranging from refactoring to using compiler inference to increase readability and shorten declarations. While those techniques are straightforward, it's clear that a lot of developers let their code get out of control, and trying to plan beforehand doesn't necessarily prevent the work from getting overcomplicated. It seems like every developer has a go-to technique (or four) for keeping things a little more streamlined. What are yours?
.
And then there is always this old chestnut... The Big Ball of Mud.
It seems like every developer has a go-to technique (or four) for keeping things a little more streamlined. What are yours?
The mess is just part of coding. Deal with the mess. Accept the mess. Live with the mess. Join with the mess. Speak with the mess. Hear its answers whispered into your head. Nod assent as the mess intones its instructions. Welcome the mess in and let its tendrils throw through your veins. Understand the mess's greater plans and become its corporeal servant on this earth. Hail the mess. Hail the mess. All hail the mess. HAIL!
He's the sort of person who would sell the Red Cross to Dracula.
No really, do not do this unless you actually need to make changes in the area involved. Diving into old code just to tidy it up brings its own set of risks, and they may simply outweigh any 'niceness' advantage.
Instead - black box it. Interface it off. Make your new code structured, shiny and gleaming. Do black box-style testing (inputs vs outputs, almost like futzing) against the old code's API and make sure your interfaced version produces the same. Unit test the hell out of your new code.
Over time, should you actually find a genuine need to, you can then start to look at the black box. Can it be made into a series of smaller black boxes? Can you interface those off too, independently? Cool - do it, one at a time, and use the same approach you used before. Eventually you'll either be left with nicely restructured code or, more likely, nice code that changes often and gnarly horrible stuff that doesn't change ever, but that's hidden behind an interface/library/<insert abstraction methodology here> and works.
Should always weigh the operational risk of changing ugly-but-known-quantity against shiny-but-unknown-quantity. The path of what to do will be different for every case.
Ok... it's DICE but I'll bite... What I have found: IF time allows, the technical debt can be revisited and cleared/reduced. Some schedules don't allow for this, but during non-peak times (like the week between Christmas and New Years) when stuff is slow, I like to revisit some of the bad places and do damage control.
.02
I think spotting these issues, and giving the developer enough time to re-visit the bad section of the code is ESSENTIAL to maintain a relatively clean code base.
Code reviews can help, but the project deadline pressure-cooker usually prevails. My
The best way is likely by not reading a Dice article.
But seriously, the main problem is that many developers don't give a shit about the quality of their work and no one notices or does anything about it. It's not a matter of learning a technique.
If there's no rigor around what you write or how it gets tested, software will turn out shitty. If the development issues can't be fixed, it's often easier to just lie to the client or use hacks and workarounds to hide problems.
The fault for this lies with management. You need to police your developers but also treat them well enough that they're invested in writing good stuff. You need to hire good people and provide your mediocre developers with good examples to follow. If your developers think they're going to be fired long before they have to maintain anything, they'll probably turn the shittiness up to 11 out of spite. if they anticipate quitting over compensation or overwork or work-life balance, how good is their code going to be? If they hate your guts because they're on a visa and getting taken advantage of, how good is the code going to be?
Are you sure you know what those terms mean? (e.g., Fast but simple solutions often create technical debt.)
When your question gets closed on Stack Overflow, then try to ask it on Slashdot?
Frankly, if your code is constantly getting out of control and becoming unreadable, you are not doing professional work, you are doing amateur work (and yes, I know that there are plenty of paid professionals who do amateur work. We've seen stories from Trend Micro programmers here recently on Slashdot).
It's not a set of rules to follow. If there were a mindless algorithm to follow, then a computer could do it. Instead, when you are about to write code, always ask yourself, "How can I write this in a way that future programmers can understand it?"
"First they came for the slanderers and i said nothing."
Think more. Write less.
Writing less code has many benefits:
Ideas that involve writing a ton more code to do X always backfire, the latest being TDD/IOC. That stuff is nearly impossible to read and maintain.
KISS (keep it simple, stupid)
Peter predicted that you would "deliberately forget" creation 2000 years ago...
has a go-to technique
How did they know my technique!?
Understand the problem it addresses better.
Post may contain irony: discontinue use if experiencing mood swings, nausea or elevated blood pressure.
Developer David Bolton has moved on from Dice and the remaining authors have been left scrambling trying to pull his notes and articles etc together to generate new content. They report having difficulty understanding how he cobbled together the disparate information into existing articles and have advocated just rewriting the articles from the ground up so they would be easier to maintain going forward.
No one, absolutely no one, wants to read your shit articles. Stop pumping them into the feed.
Basically, I used to refactor constantly whenever I maintained code.
When sarbaynes oxley was passed, every change had to be approved by lower, then mid, then upper management in a series of 6 meetings. Doing anything except exactly the enhancement they wanted was virtually impossible. There is never a good cost/benefit for cleaning code when you think that way. Any change outside exactly what was approved would get you written up.
I went into management. Programming ceased to be engaging. it was easier to argue for code cleanup a couple times a year as a team lead than as a programmer because we had two people saying it would be beneficial.
But...
*Changing non-meaningful variable names
acnum to AccountingCustomerNumber
This was the number one way I helped other programmer's fix their bugs. I would just ask- what's this- okay rename it. what's that- okay rename it. And after a short time (20? 30?) minutes they would see the bug themselves. After comments like, "Why do I need a long name- we only use this variable a few times.
Refactoring any routine where the actual code was over a page in size into subroutines.
Running performance tools to locate "hot spots".
She was like chocolate when she drank... semi-sweet at first and then increasingly bitter.
It is in having detailed requirements and performing proper testing. Good requirements will lead to good tests which will detect most of code defects. Doing structural coverage will also find not needed code.
When I take shortcuts because I am in a hurry, I try to leave breadcrumbs. I put comments that start with the string "FIXME" and then write a quick sentence or two explaining how I would do it if I had more time. Then later, when I do have time, I can just grep for "FIXME" and find a list of things that need to be fixed. Those comments save me a lot of time, because I have an explanation from when it was still fresh in my mind, preventing many "WTF moments".
These books provide much better information on the topic and deserve a place on your shelf alongside the GoF's Design Patterns.
Oh, and don't forget to always tell everyone how much being a dev sucks. Put a big "BIG SNAKES INSIDE!"-sign up on the tree-house,to keep new kids out.
+4 insightful? Is everyone with moderation points 14 year old?
My first program:
Hell Segmentation fault
#include main() { long long P = 1, E = 2, T = 5, A = 61, L = 251, N = 3659, R = 271173410, G = 1479296389, x[] = { G * R * E * E * T , P * L * A * N * E * T }; puts((char*)x); }
I think what everybody is hating on is the undisclosed relationship. Nerval's Lobster is a shill account. This is not ethical business practice.
One of the checks I do is to have a non-programmer just READ my code. If they can make any sense of it (Think variable and function names) then I continue. If not, I rewrite until it reads like English (with extra stuff in the middle :-)
I also have SHORT (as in a single line or perhaps two) comment block at the start of anything that isn't immediately obvious. This adds to readability.
I have code blocks that are more than 10 years old, that I still refer to and which I can make out the intent and the execution without issue because of these two very simple techniques. '$a' doesn't tell me anything. '$account_name' does. Stop trying to limit your typing load.
Other thing I do, which I find missing from a a great many things; Check your inputs and your return values. As much as this is Programming 101 level stuff, it is remarkably absent from so much code. How is it that SQL injection works at all?
+4 insightful? Is everyone with moderation points 14 year old?
Apparently, and it ignores the simple fact that Dice probably sucks small and medium dicks as well.
So, in keeping with the thread topic, I'll simplify the original statement: Dice.com sucks dicks.
It must have been something you assimilated. . . .
I agree about code reviews: in fact I consider them essential in a team environment and wouldn't want to work in a code base where they will not be consistently held, at least going forward. Then the team can agree on some kind of standards and I recommend that the team develop a checklist for things the reviewer should check, where near the top of the list is: "Would I want to maintain this, and could I understand it easily if I came back to it years from now?". Also somewhere on the list is: "How was this tested?". Nothing ever gets into the master branch without such a review. Ideally the review is asynchronous, at least the first pass, to help see if the code is clear without its author explaining it.
Also, the coder should review his own code first with that in mind, before sending it to someone else to review.
Otherwise code becomes a mess. On a team small enough to enforce it, things can go much better.
A Free, fast personal organizer for touch typists: onemodel
Also don't do any string validation from user input.
All that stuff is just extra cruft that gets in the way of clean looking code.
My eyes reflect the stars and a smile lights up my face.
> Make sure you understand the implications of every line you change (yeah, that's slow).
A complementary technique I used recently was to make sure I did NOT understand the code. I could understand the implications of changes, avoid any side-effects, by not trying to understand what the code did and instead applying mechanical transformations. I got a new job, working on a code base I'd never seen before. I made some significant improvements by refactoring code while making sure I didn't understand anything about what the code did. Basically, I saw something like this:
for (i=0; i = 1_000_000_000; i++) { ...
foo = 'bar';
fi = 'bee';
printf(foo, fi);
}
I could change that to this and know it was write, without understanding anything: ...
foo = 'bar';
fi = 'bee';
for (i=0; i = 1_000_000_000; i++) {
printf(foo, fi);
}
Similarly I could cut-paste blocks of code into functions, without caring what that block of code did - I only cared about which variables it accessed.
Or when I saw this:
cnm = get_customer_cumber()
I could then rename the variable via search and replace to cnm to customer_number throughout the scope. I don't know or care what a customer number is, but I know "cnm" means "customer_number", so I can do that search and replace.
So I'd say you can choose to either a) understand the code well or b) assume you don't understand it at all, and therefore make provably equivalent transformations, such as renaming, properly extracting functions and subroutines, etc. What's dangerous is when you make changes based on an imperfect understanding, when you -think_ you know what the code does, but you're wrong. You can go a long way while knowing that you don't understand it.
Or just write it correctly the first time? I know it may be harder and more time consuming, but you'll get further in your career if you do.
Depends, in R&D I write an awful lot of throwaway code - maybe as much as 80% (depending...) but, at the outset, I can't tell you which 20% will be kept and used in the product and which 80% ends up being "investigatory."
Sure, you could just rewrite the 20% from scratch and "do it right," but that's not as efficient as reusing the proven test mules - which usually aren't in too bad of shape, if you trim off the FIXME: and TODO:s.
In my career, being able to show working code, quickly and easily, is important - much more concrete than sitting in a meeting and drawing bad sketches on a whiteboard while waving hands and attempting to explain things to people who all visualize verbal explanations differently.
What you suggest is the right way to do it
It is almost never the right way to do it. Specs change, or are incomplete, or don't even exist. So it is better to hack up something quick, make sure it is what the customer (or your boss) actually wanted, and then go back and do it "right". It is silly to waste time making code "perfect" when it most likely will be thrown out.
"What you suggest is the right way to do it, but it depends on having time allocated to doing it the right way and a manager who gives a crap"
On one hand, you already have been told that's not usually "the right way to do it" since allowing for features to go along and see, once they are tested in real world, which ones will stay and which ones will not is usually the best way to go.
On the other hand, unless your manager is both a micromanager *and* technically competent, don't think about what your manager can do for you but what can you do for your manager.
If you think a bit about it, he's completely at your mercy and the code can not be "done" till you make it "done". No, not when you *say* it's done, but when you *make* it done: don't think about refactoring the code and refactor the way you write it instead, and even if your manager is the kind of "you say it's a mock up, but it looks good enough for production to me", if there's no box, no screen, no output, it won't be done even for him. Instead of coding "the happy path" first and then go after the corner cases (and never have time for the corner cases), go with the inner parts first and make your code so it doesn't do anything useful till you deem it good enough (and don't fool yourself: it's probably "good enough" quite before you usually think).