1
\$\begingroup\$

I am currently working on a project. Some time ago I realized that I do achive my goals but the more code and prototypes I add the more I feel like there is no going back. For example some of the data-structures, methods and parts of architecture I implemented could be made more productive and reusable. But this would need a refactoring nearly from scratch.

So I wonder, is it a good decision to reedit a project as soon as I realized it's flaws or should I finish all the prototypes and then create a final and clean version?

I think it does matter that I am a solo developer.

Thanks in advance.

\$\endgroup\$

closed as off-topic by Sean Middleditch, Josh Aug 7 '13 at 17:36

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Programming questions that aren't specific to game development are off-topic here, but can be asked on Stack Overflow. A good rule of thumb is to ask yourself "would a professional game developer give me a better/different/more specific answer to this question than other programmers?"" – Josh
If this question can be reworded to fit the rules in the help center, please edit the question.

2
\$\begingroup\$

Well, this is what I do. It works for me, but other people might find they use different methods.

Refactoring pays off.

Continuously refactor and rework the code. Code is more like clay, where you continuously remold it, than some kind of brittle structure that you set up once and use forever. You can always go back and improve bits you don't like. That said, you have to be extra careful not to break anything in the process of refactoring. There may be a point of spagettiness beyond which a body of code may be nearly unsalvageable -- ie when even reasonable refactoring exposes bugs that you never would have guessed would pop up. If your code base is in that state, then you have 2 options:

a) Sit down and refactor, fixing bugs as the appear

b) Don't refactor, push the project to the end, and next time make sure to write better code!

\$\endgroup\$
  • \$\begingroup\$ Consider also the debt metaphor, which says code you write under an incomplete understanding of the problem will have to be refactored (your debt). But as long as you "refactor before interest accumulates" (and have written clean enough code that it can be refactored), having "borrowed" will leave you further ahead in the long run. \$\endgroup\$ – bobobobo Aug 16 '13 at 14:24
2
\$\begingroup\$

Generally the earlier you fix the flaws, the less money/time you lose compared to fixing them later. These errors/inefficiency tends to stack up. There's plenty of literature on agile development though and working iteratively. That being said, refactoring should be a part of your work cycle.

\$\endgroup\$
2
\$\begingroup\$

Two conditions matter:

If you're working on a single, long lived project then refactor as soon as a good case can be made for the change. And by "good case" the criteria should be how many new systems will have to work against this code, how often does the code surrounding this change, will this change actually make it easier to use or is it just to be pretty? Will it save you time?

If you're working on multiple, sequential projects then simply mark it for a refactor and do the work when you start the next project that uses it.

The big point is that you recognize a real need versus just wanting to do it differently because, as a single dev, your time is precious. And once the need is determined, do it inline with your other work so it's part of your normal workflow. Continuously evaluate how well your code fits together and serves its purpose and continuously improve code if it meets the criteria above.

At some point also look at your overall architecture; if changing one section of code requires lots of external changes then modules are too tightly bound and that may be what's causing you to need big rewrites...

\$\endgroup\$
  • \$\begingroup\$ Thats it I think my classes are to tightly bound. \$\endgroup\$ – チーズパン Aug 7 '13 at 17:26
1
\$\begingroup\$

I think that you shall do a continuous refactoring throughout your project. That's part of the normal work flow. Do it in small steps, and continuously!

I always leave a TODO comment where something can be improved, and then I can do those improvements when I feel for it. I try to keep the number of TODOs at a manageable number. Maybe around 50 items. Larger redesign work is put in my backlog.

One more comment. I think the most important thing is that the code and structure is clean, with good responsibilities to classes etc. That's more important that reusability. You can do the reusability modifications if the code in question will be reused. Most code won't be reused :)

\$\endgroup\$
  • \$\begingroup\$ Well, it depends on what the code does. Vector, Matrix math, Logging classes will see high reuse. \$\endgroup\$ – bobobobo Aug 7 '13 at 17:23
1
\$\begingroup\$

The real thing you want to consider is why you're refactoring. If there's some tangible benefit you get out of it, sure, refactor when you see the need. If not, you can put it aside.

For example, I tend to do major architectural refactorings project by project: I commit to small project (order of months), and any major changes (like moving towards an entity/component architecture or a data-driven design) I commit to when I start on the next project.

On the other hand, for long-lived projects, the bigger driving force is technical debt. Like financial debt, it can slow you down or even kill you off. In this case, as soon as you know there's a problem, and it makes sense, fix it.

When does it make sense?

  • When there's some value you get out of the change (eg. makes it easier to do X)
  • When you know the change is inevitable (must be done)
  • When there isn't a looming deadline (intermediary release, milestone, etc.)
  • When you can afford the time to finish the change

To summarize, it really depends on the needs of the project and your availability. Personally, I try to integrate small refactorings as I go, and leave major ones for the next project (which is not too far off).

\$\endgroup\$
1
\$\begingroup\$

For further reading, you should study the chapter A Pragmatic Philosophy/Software Entropy from The Pragmatic Programmer by Andrew Hunt & David Thomas. It deals exactly with your problem here. I will drop this quote from the book:

One broken window, left unrepaired for any substantial length of time, instills in the inhabitants of the building a sense of abandonment—a sense that the powers that be don't care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner's desire to fix it, and the sense of abandonment becomes reality.

...

Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a "Not Implemented" message, or substitute dummy data instead. Take some action to prevent further damage and to show that you're on top of the situation.

Are you going to throw away all of the prototype's code? If not, and you're going to build upon it, then don't make your life harder by leaving broken things pile up. You may find comfort in thinking that you'll repair things later, but this also makes you oblivious to the piling, and you might just overlook serious and otherwise obvious flaws.

Tip 1: After you're done writing a method, read it again, start-to-end, and see if it cannot be refactored.

Tip 2: When you're not actually writing code, and have the time, take a few minutes to look over your code and see what can cause trouble and what can't. If you can afford it, fix everything on the spot. If not, then at least set a TODO there, and write down what can go wrong and why, so you remember the next time you're visiting the code. I call these 'quick refactoring sessions', and I perform them quite often.

I find that the most important ingredient in refactoring early and properly is willpower. Be sure to have some ready!

My third tip is extracted from the book itself.

Don't Live with Broken Windows

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.