I've been recently working on a project where I've been having a little trouble coming up with a good code structure and I began wondering about the process of coming up with the design.

When I decide what I want my program to do, before I sit down to the keyboard, I usually grab a sheet of paper and a pencil and start drawing out how the program will run. I figure out how the different options in the program will be processed. Will the program use command line options or have the user enter them as the program runs? And how can I include the options into the code without making it look messy?

I will also try to eliminate as much as possible other forms of messiness like unecessary code repetition. I try to figure out ways to structure the args passed and returned by functions in order to make functions as reuseable as possible.

I also draw out the format of the actual output of the program and try to figure out how to adjust the code to best suit this form of output. This is especially necessary for me when I am working with web applications (which this happens to be).

I make sure that in my program I can add new features with as much ease as possible. I try to isolate the algorithms required for unique features in the program so that more common functions can be reused as much as possible in later additions to the program.

So after I contemplate these and many other factors that I could not come up with at the moment, I end up with a map that I follow while I am coding. Of course, modifications always end up being made during the coding process, but at least I am not coding blindly.

So now I ask you: Do you do something similar to me? or do you find it easier to decide on design as you go along? or do you just code the necessary algorithms (the ones that you know you will need to use) first and then form the design base on how they came out? or do you have some really unique mathod for coming up design that I could not think of?

I prefer the 'worse-is-better' approach, with very little design up front. Instead, I make a list of things the program must do. Then I break each thing into tasks, and arrange them in order of importance.

It's a lot easier to design something well if it's small and if you actually need it right away. (It's also a good idea to cultivate the habit of writing unit tests *before* you implement something.)

If you do this consistently, you'll maximize the value of your programming time. Doing the unit tests will help you keep things running smoothly.

It's hard to guess what you'll need before you start programming. It's a lot easier to change things if you work on only one task at a time and if you have a baseline that will prove that your changes didn't break anything.

That doesn't mean you don't do design, but it acknowledges the fact that it's hard to do design perfectly the first time for anything but the smallest programs.

(If this all sounds familiar, yes, I'm ramping up for my XP talks at OSCON.)

Back when I was studying stuctured program design (and promptly forgot most of it and had to relearn it), I remember my instructor explaing that all programs had four steps:

Initialization

Input

Calculation

Output

Admittedly, that's a bit simplistic and I suspect that he was only familiar with procedural programming (as opposed to functional, OO, and logical). While I don't necessarily design my programs into four sections, they often break down that way.

What I usually do is start with the output. What do I want my end result to be? From that, I can determine what data I need to capture. Then, I go to the input section and figure out my data sources. With this, I have my beginning and end data and I find it relatively easy to work out the data flow (well, usually).

The data flow, to me, is the 'calculation' part. Frankly, I don't even worry about my data structures until I have some idea of what those calculations are. With that, I can often identify common elements to factor out. Once I know those, I design data structures to fit them.

I can't say that I follow this process religiously (ooh, I'm a bad monk), but what I prefer to do is something similar to this node. Also, Warnier-Orr design is something that I've enjoyed, though it often breaks down with object-oriented programming.

I do a combination of things that are mentioned, however most of my applications are striving to be the front end for small online databases (either data entry or retrival.) I start the applications by talking to the future end users to make sure that what 'I understand' as the end desired functionality is what 'they understand' it to be. Once I know that the expectations are the same, then I go back to my cave to invent and discuss with my staff.

We usually start by drawing up a series of data structures. So, I look at the programming through the eyes of a DBA first, (ie: What tables and data fields are necessary to do the job.) We have three very large white boards in our development area, and about 5 small ones that are not mounted to the wall. They turn out to be great idea generating tools during our discussion and planning stages.

Once we're satisfied that we have the data structure intact, draw up a final version on one big white board. Then we start by drawing up the form, (ie: What is the user going to use? How is it going to affect our data structure?) We usually talk out as many possibilities of entering data, etc, until we're comfortable that we have the functionality desired. We may modify our data structure if we see something that we've overlooked along the way. When we're satisfied that we've covered all of the bases, we draw up one final set of form(s) on another white board.

The last part is that I break the project up. I start people documenting what we're going to work on, doing a layout design that is efficient, breaking everything out into small tasks, making assignments, deadlines, etc. From there I have my 'map' and we move forward.

The way I (try to) work has been inspired a lot by the XP (eXtreme Programming) folks, who insist that code that doesn't directly help your program do something it has to do is code better left unwritten.

The principle is that you start with a description of what the program does for the user (well, its interaction with the outside world, anyway), as described in "stories". You then proceed to describe your system from the point of view of making only the program artifacts (objects and classes) that are needed to accomplish the tasks described in the story. You don't write any code that isn't used.

And you start by writing test cases, before you write code (so that you'll know when you get the code right). You elaborate the tests and the code until you've met the requirements in the stories.

And you continuously refactor. Don't worry about making the right architectural decisions on your first page of code. Just change the structure as you go along to meet your new discoveries.

As far as reusability, well, a great quote that I heard (sorry I can't attribute it right now) is this:

Nothing is really reusable until it's been reused three times.

Why three times? Because it usually takes at least that long to get a feel for what other users of the code might need. Don't start out by writing a framework; start out by writing an application that works. If you find that you need to reuse some pieces of it, refactor as necessary to do so. Repeat. Don't be afraid to totally change the structure of your software.

Of course, it depends on the size of the project, but I usually do something similar. I think of what my program needs to acomplish, but usually don't write it down for most tasks(but that's just my style; I have a good memory). I think of some options, well many admitingly, before I begin coding, but I don't implement them untill I have the basic code working.

I started in C/C++ studying OOP, so as a result, most of my code is well encapsulated, and easy to adjust and add features to. I like to design my programs by what is called a "bottom-up"(as opposed to a "top-down") approach. This means that I first design the functions, and make test drivers (simple code to "simulate" what the main program will do) which test the functions and make sure they do what they're supposed to.

From the drivers, it makes it easy to see what's going on at an early stage, and to adjust the algoritms and logic accordingly. Once I've got all the functions all working as they're supposed to, I combing them together and work on a more permanent main program(I guess I call it that since in C/C++ it is called main :)

That's just my personal approach, but for me it works best because it allows for easy and quick updates and it doesn't require a lot of debugging all at once(because that's what I did all along with the test drivers). It also, because I tend to encapsulate the data anyway, makes it easy to change the code into a module, if need be.

When I first think of a new project, I try and draw out exactly how the meat of the project will work. This is the first thing I attack during my process. I always catch myself trying to add features, or trying to make it sleek even before the thing works. I can usually catch myself and write those items down for later. Or "After it Works" (tm).

Once I have the basic code working, I start drawing out all the things I want to add to my project. Then I take another look at my methods used for the working code and see if everything will fit the way I have it down so far.

The next phase for me is a little messy. I think I start to brainstorm a bit and I quickly add features/improvements all over the place. I can tell that I should learn to curb this habit before doing anything larger.

Another thing I've found is never ever release an early concept to friends. =) "add this", "do this", "this would be cool" - I learned my lesson, they get it after its done

Once I get most of the features in that I want, I start to organize myself a bit and clean up the code. I do this until I'm satisfied with the layout(functions++), then I complete any outstanding features within the new structure.

Then I release.....

Recap:

Write down outline and ideas

Get chunk working and redo working code chunk for improvements/features

With small programs, or things that are quite obvious, I just start coding bit-by-bit. Testing each step, modifying, and letting the program grow...

However, when I work on large projects I want a decent design. Either made by me, or by some software architect. I don't just start programming. I've seen it too much before: start working and half way you come to the conclusion that the design was bad and that important and you can start al over again. No thanks.

Even that piece of paper and pen of you won't be enough for large projects. Every part of the project has to be thought about before you start coding.

Went to join the gridlock to see it
Held an eclipse party
Watched a live feed
I cn"t see tge kwubosd to amswr thus
I tried to see it, but 8000 miles of rock got in the way
What eclipse?
Wanted to see it, but they wouldn't reschedule it
Read the book instead