Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I recently read a blog post (which I lost the link) that really make me think. The writer said that the one of the biggest problem in software projects is actaully completing it, and most people will end up abandoning the work.

I have been self-learning programming for over 15 years now, at this stage I actually feel pretty competent. However, I have never finish any big project that I set out to do.

What I usually do is this:

  1. I "sketch" my idea in code, compile and run to see if it works, and imagine how other stuff can come toogether.
  2. As the "sketch" becomes messy, I start to refactor it, consolidate functions, make classes, re-organisation data structures etc.
  3. Repeat 1 and 2.... forever!

I tried to write on paper UML diagrams etc. but it always end up with things I overlook and then requires some drastic changes and then I becomes 1, 2, 1, 2, 1, 2 again.

How does commercial projects handle deadlines? Should I just keep on sketching until the final product is completed before thinking of making the readability/reusability/architecture/engine more sound?

share|improve this question
    
Lately, I have been reading Dijkstra perhaps a bit too much, and (this is the scary part) putting his ideas to practice. So I have found myself painstakingly deriving my designs from formal specifications. –  Eduardo León May 9 '12 at 9:31
2  
For commercial products, they just "pick two" from: en.wikipedia.org/wiki/Project_management_triangle#Example Something that's 80% done in the wild makes more money that something 99% done in the lab. –  StuperUser May 9 '12 at 10:00
2  
Usually, quite a bunch of people work together to create a big project. When I was young (say 17..25), I also started some relatively large hobby projects that were never finished, and looking back, I can safely say that the total effort to make them a real product would have exceeded my resources by far. –  user281377 May 9 '12 at 11:12
    
Asking questions of the form "your answer is provided along with the question, and you expect more answers: “I use ______ for ______, what do you use?”" is not constructive - FAQ. –  ChrisF May 9 '12 at 14:41
add comment

closed as not constructive by Jim G., Jarrod Roberson, ChrisF May 9 '12 at 14:40

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

6 Answers

up vote 5 down vote accepted

Welcome to the wonderful world of Project Management plc!

I've found that there are two extremes to programmers/developers:

  1. The Ship-it-now
  2. The Charles Winchester

The first type should be self-explanatory (they're the type of developer who wants to get the work done and shipped as fast as possible, fixing any bugs later), whereas the second type may need a quote to explain:

I do one thing at a time. I do it very well. And then I move on - Charles Emmerson Winchester III (MASH)

It's the difference between writing an app that calculates a percentage for a given value using a command line interface with no checking (Ship-it-now), and a version with full input checking, rounding error notification and a custom GUI.

The process I use to write software is:

  • write the code (as per the spec/design document, or as close to it as is possible)
  • before it's committed ask myself "am I happy (within reason) with this code?"
  • ask a fellow developer if I can talk through the code with them

That way I can explain why I did things the way I did and they can give me input before I refactor/re-design or commit it back to the master branch.

You could spend years and years re-factoring or re-implementing code, fixing new bugs as they arise (and they will) or you could ignore feature creep and the need to redesign and ship something actually that works (with a few bugs... maybe).

As others have stated, it sounds like you might be working on your own (not part of a development company). At the end of the day, a development company HAS to have something to sell, otherwise they'll go out of business very fast. To that end, most project managers will not allow a developer to keep working on a piece of code that (to all intents and purposes) works, but looks a little nasty.

Don't get me wrong, I used to code they way you describe. But this was for pet projects or for unimportant code that would be given to relatives/friends.

Imagine that you're building a car or a house. You don't want to sell something that doesn't work (caught in the refactoring/re-design stage for too long and there are real projects that are like this - the big one of recent times was Duke Nukem Forever), but you also don't want to sell something that has major problems either. You need to figure out the best balance. Hopefully, the best balance would be a completed product with few to no problems (any huge piece of software that you can think of); but that's not always the case.

Giving yourself deadlines might help to teach yourself the necessary skills in project management. I know that when I was at uni, all of my assignments had a 25% time management mark - if you couldn't prove that you'd managed your time well (Gantt charts, recorded lecture and tutorial attendance, recorded use of the labs, etc.) you'd lose marks and potentially drop a grade.

share|improve this answer
add comment

The main difference between you and a company is that a company has to produce something or it loses money, so it normally gets hammered out before the molten metal cools. By that I mean, while nothing is carved in stone, ideas are shaped and bent and a project begins its long cycle with the initial decisions made. As time passes, it becomes increasingly difficult to change as you probably know by now.

However, where a normal programmer might scrap it in favor of a new design, deadlines at work make it so that you don't have that luxury so you have to make it work, performing whatever adjustments needed to get it done by the deadline. The end result is that if it wasn't a well-shaped idea to begin with, it has bumps and scratches and generally looks like it was forcibly made to look that way rather than a piece of art.

While it's true everyone wants to stare at a piece of artwork, there's a fine line between making something which takes a long time to make but is done remarkably and something which is done sooner and is cost-effective for the time put into it.

With that said, I find myself doing exactly what you do at home. 1, 2, 1, 2. The only conclusion I can gather is that there is so much room for improvement, that it's hard to ignore the flaws we've made thus far.

share|improve this answer
add comment

I think it's a bit of a false dichotomy really. Many productivity guides or programmer advice boards paint this idea that you either: 1) perfect the code and never release product or 2) rush out buggy half-finished code. In reality, most of your work is maintaining old code (yours or someone else's) not implementing brand new things completely from scratch.

In that light, taking the extra time to clean things up is almost always better, I find. In the long run, the time you save by refactoring towards better design beats the time you spend fixing up bad code. This effect compounds as well, as usually if you aren't working towards a better implementation, you are adding to a worse one and making it harder to change and maintain it later.

For new software, this notion interestingly leads to the opposite conclusion. Since you will be maintaining the code for a while and it's very hard to get the ideal design up front, it is usually best to get it out the door with the best design you can work out at the time. Once it is in the wild, the design will evolve through maintenance into what it needs to be.

share|improve this answer
add comment

Speaking from my experience, I've found that it is a balance. Starting a new project and molding the architecture as you go is more difficult than maintaining an existing project. With new projects, you have a blank slate of sorts and it's up to you to define how it is structured. Existing projects already have this defined and give you some constraints to work under, limiting your choices and, because of this, potentially giving you a quicker time to implement.

I would say it is unfair to compare your personal projects to your professional projects. Personal projects are your projects and you should use them as an opportunity to objectively try new methodologies and technology. That is, unless you're writing the project purely for the functionality, in which case - why would you place more weight on the design versus the functionality?

With respect to UML diagrams, I've not had any experience in using them for project design. I tend to think that they are a bit heavy handed when the company considers the most important thing is to ship code. Because of this, I tend to start coding at a high level after giving it some thought to the approach of what I want the final product to look like. I consider maintainability and readability to be the most important factors at this point. Another problem with the documentation is that it has to be read to be useful. You could sketch a UML diagram to help you think through design, but even if you package up all of your documentation later, will anyone actually read it? Unread documentation is not useful.

Regarding the "code, refactor, code, refactor" cycle, you only need to do this when you need to improve the code. Avoid refactoring for the sake of refactoring. Take the approach that you are making necessary improvements to the architecture. I usually do minor refactoring (extract to method, naming conventions, etc) and leave major refactoring (architecture, class structure) to the times when I'm enhancing the system or fixing a particularly nasty bug that seems to be the byproduct of the design (or lack of it). I have seen many places that would benefit from refactoring, but if the function is working, I don't mess with it unless I think it's necessary. In the short term, I will still make the minor refactoring adjustments just so I know things are improving.

At work, I try to keep in mind to "leave things better than you found them." This doesn't mean I'm continually refactoring code with every change, but that if I am making a change that is significant enough to warrant an evaluation of making it better, I consider the options (also weighing in the amount of time it would take to implement along with risk, maintainability, etc) and choose the best bang-for-the-buck option.

Part of the advantage of working on a team producing applications is that you get exposed to alternative methods of design. You also are made aware of obvious short-cuts in design or implementation to get it out the door. The consistent example I come across is the lack of use of polymorphism versus the use of variables to control behavior. The former takes a little more effort to implement and is usually more maintainable and less prone to weird behavior. The developer may have thought that (s)he was just reusing the code that is already there, but the long term maintenance weight that carries is not always insignificant.

Regarding commercial project deadlines, there are many variables. Not all projects are on a death march, although it seems to be fairly common to value the shipping of code over its quality. End users do not care about any fancy designs you may have implemented, much less your choice of dependency injection container. They are more concerned with well performing, accurate, and reliable software that gets the job done.

share|improve this answer
add comment

Should I just keep on sketching until the final product is completed before thinking of making the readability/reusability/architecture/engine more sound?

Here is the thing. The final product probably doesn't even exist even in your dreams. How can it be completed? Compagnies are selling software with support, which precisely mean that the work will keep coming. The only "finished" projects are the dead ones (with a few exception).

So yes, if you are working in a compagny you should care about readability/reusability/architecture before the end of a project because you will be more productive (and there is no point in caring after ...). That said, caring about something does not mean that it should be perfect (I don't think this word has any meaning in softwares anyway). It means having a pragmatic approach about developpement, and not solving only short term problems by creating long term ones when there is no need to.

For your pet projects, do what you want. If you are the only user, do what you enjoy i.e add functionnalities or refactor. If you have other users, discuss the matter with them.

share|improve this answer
    
Sometimes it's not adding features, but how something done 3 week ago could have been done in a better way. In that case, should we go back and make the change and delay the rest or just leave it in its current state/mess. I find it hard to decide since the benefits cannot be measured immediately. –  Jake May 9 '12 at 11:53
    
There is always the benefit of learning. When you read a piece of code you see things you can improve. By doing it you are trying different alternatives to solve the same issue, which is a good way to learn. Once again it is a matter of context. If you are building a pet project and you are in the mood of learning, then rewriting is more important than finishing. In software compagnies, you have to define clear goals for the rewrite and sell it around you. –  Simon May 9 '12 at 12:03
add comment

Agree with the other posters that it's a balance, you need to be pragmatic, and need to understand the commercial incentive for shipping early.

That said, I would still tend towards doing things well & doign them right the first time rather than coming back later.

If you layer poor and rushed code onto poor and rushed design decisions, you end up with a tangled mess thats hard to maintain and extend surprisingly quickly.

When you're under business pressure, you tend to live with and press ahead with these compromises for longer than you intended, but sure enough they will begin to have more and more of a hidden cost in terms of productivity and quality of the end product.

Before you know it, you're completely backed into a corner due to all of the shortcuts you've made. But the alternative of rewriting all of this junk can end up looking a big task in itself with the 'fixes' you put in breaking something else in the application.

As a developer, you obviously dont want to come across as a perfectionist who will never ship because he's refactoring his code for the 100th time. However, you do have a bit of a professional responsibility to push back on being told to take short cuts or ship junk by at least explaining the downside of technical debt.

share|improve this answer
add comment

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