I know it's one of these questions that come back endlessly, but I really need your advices :)
I'd like to hear from you about the design and programming methodology you follow...

Until recently, when I started a new application project I first drew a sketch of the application, then I started coding by the "main", adding subs as needed.
Unfortunately this tend to give spaghetti code; I had too often various unrelated code blocks stuffed into the "main" routine, and I had quite a hard time splitting the program into files/ librairies/ components.

Then I tried to start the other way around; first, I draw the general application schema, but I start first by programming the first components I need. Then I write a "main" program which actually does pretty much nothing by itself, but uses the librairies or objects already done, so I can test them.

Here I am now. The second approach seems much cleaner and better to me; but it comes at a price of longer time spent and harder work, because I have to build very clean objects from the start, instead of throwing together some dirty code that just "does the trick".

I can imagine another way, of course: I may try my first method, but keep refactoring as needed the "ugly bits" while working, instead of having the code working first...

What do you think?

Replies are listed 'Best First'.
Re: How do you program (again)?
by kirbyk (Friar) on Jun 02, 2005 at 21:44 UTC
    It depends tremendously on the task at hand.

    If I'm doing something that will take less than half a day, and be used only once or twice, just diving in and doing it is an excellent approach. Even if you find out that your script is tremendously useful and is used all the time, you've only invested a half-day in your prototype, and can rewrite it without throwing out a ton of work. No need to enter analysis-paralysis - perl is very good at rapid prototyping.

    However, anything that's going to take longer than that, needs some more thought.

    Sometimes, you'll have a good idea what you want - particularly if you're rewriting a legacy appliction, for instance. Getting a good database schema and object design done in advance has proven to be a worthwhile approach. Write this stuff down - it's very handy if you're working with other developers and/or QA engineers, and helpful for you to flesh out your ideas even if you're not. Being able to write a technical specification is a job skill that will never be a waste. Have someone else take a look at it. If your design looks good, handles the scenarios you can throw at it, and solves your problem, go ahead an implement it. Preferably little testable chunks at a time.

    But, often we don't know what we really need when we start. If possible, design a prototype. You'll learn a lot more by solving a small, representitive part of the problem set than by just thinking about it. And you can get feedback from the customer that you're on the same page - few people really can tell from specifications what it's like to use a piece of software. After this, you're in a great place to do actual design work.

    It's almost always worth the time to design objects, rather than throw them together, because you'll spend less time in maintenance. All software evolves in the business world, and the best designed software will eventually be full of hacks and special case code and need to be redesigned, but you can make it a lot farther off with some good investment of time up front.

    -- Kirby, WhitePages.com

Re: How do you program (again)?
by jweed (Chaplain) on Jun 02, 2005 at 21:16 UTC
    Perhaps you should check out Code Complete, which is an excellent introduction to precisely this probelm: how do you take a general idea and turn it into modules and routines. It is highly reccommended.



    Code is (almost) always untested.
    http://www.justicepoetic.net/
      I highly recommend, also: The Pragmatic Programmer. This book is less about programming idioms and more about philosophies and approaches. It was given to me when I finished my first software engineering job, and I wish I had it to start with. In fact I've bought copies of this book for brothers, friends that were interested in becoming programmers.
        I cannot stress how much I love this book. I have one copy at the office and one at home.
      Thanks, I'll buy it.
Re: How do you program (again)?
by spurperl (Priest) on Jun 03, 2005 at 06:37 UTC
    Inspired by Lisp, I prefer the method of bottom-up programming. In its essence it's simple:

    You have a task - T to solve. So, you don't just write a program to solve T. You first write a whole new language for solving tasks like T, and then you use this language to solve T.

    By "language" I don't mean a whole new programming language (though with Lisp's powerful macros, which thankfully found their way into Perl 6, it looks this way) but rather a new level of abstraction (functions, classes, data types) above the basic language that helps to solve the task easily.

    Such design results in very few bugs and immense flexibility. The flexibility comes because while requirements often change, they most commonly affect the "top layers". If you have a powerful abstraction, you recode those easily.

    Naturally, some mix-in of top-down design is also required, but that's only when the task at hand is large and comprises of several large sub-tasks that can be independent.

      I see, that's more or less the way I follow by now. My concern is that while I build tools and objects, I postpone the time when I write the actual program that will do "the task". Beforehand, I used to write a program that more or less did the task, then improve it gradually... easier, but hard to maintain.
        One of the benefits of the technique I presented is that it's actually easier to reach a working program quickly.

        When you write in layers from the bottom up, you test each layer which is simpler than the whole program, and thus assure yourself minimal bugs (debugging usually takes more time than code-writing). When you write the next (higher) level, you rely on a tested lower level and have more confidence. Massive unit-testing along the way and you're set for a working, clean solution.

Re: How do you program (again)?
by dragonchild (Archbishop) on Jun 03, 2005 at 13:39 UTC
    I suggest you follow how Pugs is developing. Essentially, autrijus has offered to write code to make any failing test pass that someone writes against Pugs. Here's the cool thing - by doing it this way, he guarantees that he never breaks anything that used to work.

    Here's the other cool thing - he only ever is trying to make one thing work at a time. He picks a failing test and says "Ok, I'm going to work until this test passes" and does the absolute minimum to make that test pass. Then, he runs the rest of the test suite (to make sure nothing broke that used to work), then checks in the changes to SVN. Often, he'll check in 2-3 lines changes. There are usually between 10-100 checkins per day into the Pugs repository. A lot of those are new failing tests, but Autrijus makes a lot of those tests pass very quickly.


    • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
    • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
      Interesting. What I currently miss is a proper test suite... I was in such a hurry to ship the code that I missed the time to do anything else, including learning how to write a test suite, then write it!
Model the data first
by mugwumpjism (Hermit) on Jun 02, 2005 at 22:55 UTC

    First, I model the data, and the relationships between the data. Sometimes I'll use an editor like Umbrello, or simply sketch some UML on some paper. Other times I'll just hack Class::Tangram classes directly (as Class::Tangram has quite direct correspondance to most UML data model forms).

    Once I've got this model (represented as Class::Tangram classes), I'll write test cases for each class that tests any "special" actions that the object needs to do, for instance, password encryption and authentication on a User object.

    The next stages really depend on what the application is doing. Sometimes the next stage will be to plug the classes into a Tangram::Schema, so that I can save them to a database. Sometimes the database plays a more direct part in the planning stage, if there is an existing data form I need to represent and map to.

    I find that once the data model is good, writing the actual program is just a matter of joining the dots... which of course can often take a lot longer than you think ;-).

    $h=$ENV{HOME};my@q=split/\n\n/,`cat $h/.quotes`;$s="$h/." ."signature";$t=`cat $s`;print$t,"\n",$q[rand($#q)],"\n";

      I'll second the notion, and try a paraphrase:

      • Model the data first: give yourself nouns.
      • Decide what the application is doing: give yourself verbs.
      Make it easy on yourself, too. Get Code Complete and Design Patterns. Find out what UML is, and if it fits your way of thinking, use it; but don't force it, or get caught up in dogma. I use bits and pieces from 6 different programming "schools" - Waterfall, Rational, Extreme, etc. Do what works best for you, and you'll be most productive. Find work environments where this fact is respected.
        I've worked a bit with UML 4 to 5 years ago, and quite frankly, it confuses me more than it helps : I find too often that the nice UML blue-print doesn't fit well actual data, or workflow, and has to be trashed after the development has already advanced quite far. Maybe that's just me...
        Proper datamodeling is very important though, but I prefer thinking it directly in Perl, or relational databases, or whatever else I'll be using to manage the actual data.
Re: How do you program (again)?
by adrianh (Chancellor) on Jun 03, 2005 at 08:25 UTC
Re: How do you program (again)?
by NateTut (Deacon) on Jun 03, 2005 at 12:47 UTC
    One trick I use is to write the comments first. This will focus you on what you need to be doing and not getting bogged down in the nitty gritty of making it work.

    Also start small. Once you have the concept of what you need to do clear in your mind, find a small part of it that you can get working. Then build on that adding in small increments, always making sure everything is working as you envisioned before adding on, this way a large complex task can be made doable.

    Perl helps enormously in this process. I have had to work in VB in the past. In VB you do things Bill's way or its the highway. I always managed to get things done in VB but it felt like swimming in mud. With Perl I do things the way I think they should work and more often than not it does work.
Re: How do you program (again)?
by steelrose (Scribe) on Jun 03, 2005 at 21:39 UTC
    I take a not-so-structured approach, trying to determine ahead of time how involved the project is going to be, then diving into it if it's not too involved, or blocking it out before hand if I think it's too involved.

    That leaves me burned when scope creep occurs, but I've really tried to ask enough questions up front to keep that from happening as much as possible.

    It still occurs though.
    If you give a man a fish he will eat for a day.
    If you teach a man to fish he will buy an ugly hat.
    If you talk about fish to a starving man, you're a consultant.
Re: How do you program (again)?
by TedPride (Priest) on Jun 03, 2005 at 17:48 UTC
    Divide the program into discrete sections, then figure out what functionality (modules and/or subs) you'll need for each section. Design all necessary subs and perform proper testing; put together the sections and perform testing on these as well. Small programs can be thrown together willy-nilly, but larger programs will require several layers of coding and testing if you don't want to get into a terrible muddle.
      Well I am in muddle, because I didn't take the time to really make the things just "right". However I test each new small code block (using small test scripts) while I write it, and I check that it pass perl -c every 5 seconds, and I stop to test the code I just wrote after 20 minutes max -- so it's not that bad actually; it pretty much works, but the apps I'm working on are very complex, multi-process (with possible deadlocks...) data management systems...
      So now that I'm about to close a project and while I'm already working on the next one (this one very late too, of course :) I'm trying to meditate about it to make it much better than the previous one :)