views:

352

answers:

6

Hi, I've started working on a fairly complicated software. It is for a personal project, but nonetheless I'm putting a lot of effort into it. Now, I'm used to work on other people's solutions / designs or on projects that grow in a very controllable way.

This time, I started twice to code the basics and I rapidly found myself stuck. So i took a rest and decided to write down the complete solution before coding a single line. What I've done (in order) is:

  1. writing the use cases in the form of CLI commands (this is a command line application)
  2. write some help
  3. design the classes, the structure of the data files and the functional workflow for the various parts.

Now, I'm going really slow in this whole part. I've set up a personal wiki and I'm using it to write those specifications, but i clearly feel my lack of experience and a clear methodology.

I'm aware that software design is a very complex subject and that a pletora of books have been written about it, but I'd love you to share your experience / advices / methodology.

When working on personal, middle-sized projects, what do you specify before starting to code? How?

Thanks in advance

+7  A: 

There are many people with better experience than me to help you with specifics here, but I have one point I think is always worth bearing in mind.

You don't need to get it 100% perfect first time. In fact, if you aim for that you'll probably never even finish. The reality is you won't understand the design fully until you've built the system once.

Just start, keep pushing forwards, keep on-top of unit test coverage, and as you understand the system and its intricacies better then incrementally refactor to improve it.

Andy Hume
Amen;-) Said it quite well
JoshBerke
+1, 100% perfection just isn't going to happen, that's why version numbers were invented :o)
gridzbi
+4  A: 

When working on personal, middle-sized projects, what do you specify before starting to code?

I specify the functional specification:

  • I feared that it might be too easy, if I just started coding (which is the "how"), to forget "why" and "what" I wanted to code (for "fairly complicated" software, over the months or years that it might take to develop).
  • I also wanted to understand, more or less, the "scope" of what I would be developing: in order to assess approximately (to an order of magnitude):
    • How big it will be
    • Whether I could finish it
    • Whether it was worth starting
    • What subset of it can be developed first

For the sake of risk management I'll add that some of what I wanted to develop implied using some software that I wasn't familiar with; to minimize the risk associated with that, I also did a little throw-away prototyping.

How?

I outlined a functional specification, using pen a paper. Some of what I wrote was high-level (a business-level "vision" document), and some was lower-level, more like design (some of the UI details). Sometimes I stopped and puzzled about how to organize it, but then went on, reasoning that each page is more-or-less cohesive about each topic, and that I can puzzle later about how to organize the pages (much like your wiki, perhaps).

I both did and didn't specify the software architecture in advance:

  • I start development with a basic architecture (a few small components) in mind, and then add code; and, as I add code, if any component gets too big and complicated then I subdivide it into several smaller components ... it's an evolutionary process ... as it says in Systemantics, A COMPLEX SYSTEM THAT WORKS IS INVARIABLY FOUND TO HAVE EVOLVED FROM A SIMPLE SYSTEM THAT WORKED.
  • I'm not documenting the architecture; or, rather, the only documentation of the architecture is the code itself: for example, the way in which source code is arranged into source directories, namespaces, and DLLs.

I do have a theoretical justification for the architecture as it is now, but I haven't documented these reasons:

  • I'm the sole developer
  • The actual architecture is documented by the code
  • The reasons for the architecture are in my head, and are [re]discoverable by things like the naming conventions in the source code, and the various components' dependencies

If (only if) I weren't the sole developer, then I might think it worth documenting the architecture and its rationale.

What I said above about the architecture of the software is also true of the data which the software processes.

As for testing, I code a bit and then test it; or write a test and then code the functionality which will pass that test. I'm not doing "big bang integration", i.e. months of writing without any testing.

One of the biggest weaknesses in (or thing missing from) my process is estimating effort in advance, and then tracking implementation against the estimate ... this is one of the differences between this 'personal' project process versus a paid project that I'd do for someone else commercially. I doubt whether this is good though: if estimation is a best practice commercially, then perhaps I 'should' be doing it too on a personal project.

ChrisW
+4  A: 

Basically, the screens. They are the interface between the user and the software. So I try to identified every use case (the user will search for my product - the user will add a product to its caddy - the user will check out its caddy) and I create a chain of screens for each of them.

Best wishes.

Sylvain
"writing the use cases in the form of CLI commands (this is a command line application)"
AgentConundrum
+3  A: 

I find a blank piece of paper and a pen is the best starting point:

  • sketch a few rough diagrams
  • jot down some ideas / notes
  • write some pseudo-code
  • think through main use-cases
  • think of potential problems

Don't spend more than half an hour on this, and don't get bogged down in too much documentation or up-front design. Start coding as soon as you have a vague idea of how you want to do it. As you continue developing, you get a feel for whether the code is good enough or not. If you're not happy, think about what you don't like and start over with those lessons in mind. Refactor often and soon, the earlier the better. If something doesn't "feel right", it probably isn't.

armandino
+1  A: 
  1. Draw the screens
  2. Draw the data relations (rdbms or in-memory)
  3. Start coding
  4. Lather, Rinse, Repeat (or in programmer-lingo GOTO 1)

I would start with a minimal implementation and add more features in each iteration.

Osama ALASSIRY
+2  A: 
  1. Write the use cases like you did.
  2. Pick 1 of the uses case and implement it completely, and implement nothing else. This includes unit tests, help and error handling -- everything. Call this version 1.
  3. Implement the next use case. This may be just adding code, or may require a complete redesign. It's ok, you know what your doing now. Make a new release.
  4. Repeat step 3.
Mark Beckwith