This is my rule of thumb on evaluating software - it must be flexible. The flexibillity can come from many places. The lowest level is source code, there you can do a long jump, but it can be too time consuming to choose precisely the landing point, it should be the task of some higher level layer to adjust the jump more accurately(1). So the ideal is to have multiple flexibillity layers. The purpose of this meditation is an attempt to categorise them. Here is my list - starting from the lowest level. How do you plan the evolution of your programs? What preparations do you make for future amendments?

Update: Added protocols (thanks to chip).

1) I could make the model more precise - but it would never be precise enough - so I leave the vague metric space, long and short jumps model.

Replies are listed 'Best First'.
Re: Multilevel flexibillity
by gjb (Vicar) on Jun 23, 2003 at 12:15 UTC

    In general, I find that when using an OO approach with a granularity that is not too large I seldomly run into problems when I want to change the code later.

    Classes should map as closely as possible to the "objects" involved in the problem you're trying to solve (that's what I mean by the "right" level of granularity).

    Altering functionality can be done by using the typical OO techniques like inheritance or composition.

    For me, the threshold to introduce classes is very low, but opinions on this topic differ widely.

    Just my 2 cents, -gjb-

      The OO techniques do have their's place, but I would argue that that is not all about the flexibillity. It is for me in the lowest layer - source code, and is much more usable for the author of the code than for the 'general public', it's just too tightly coupled. Templating for webpages is a perfect example of a really powerfull technique well separated from the source code.

        I agree that OO is not only about flexibility. The main point for me is that the OO approach can match the "problem space/world" very closely. So it's mostly about modelling, the flexibility can come for free if the former was done "right" (for your favorite definition of right, i.e. there more than one way to do it ;-)

        Just my 2 cents, -gjb-

Re: Multilevel flexibillity
by l2kashe (Deacon) on Jun 23, 2003 at 13:46 UTC
    How do you plan the evolution of your programs? What preparations do you make for future amendments?

    Update: Thinking about it the whole point of my post is stating that I think there are 2 lower points than the source. The lowest being what the software must do within certain constraints. The next being what would be nice if the software could do.

    First I like to attempt to define the problem space appropriately. Second I spend the time to look at what does and doesn't work in the same problem space. Once I have these pieces a general framework has been defined, which will in turn define, at a high/vague level, the amount of flexibility needed in this particular space.

    There are some places where a great deal of flexibility is nice, ( ala File::Find ), and others where you give up flexibility for some other prerequsite (security or speed). Granted those prereqs are a little contrived, but I think thats a decent example of the principle.

    Once the base has been reasonably defined, with clear goal of what the software "can/should" do, then you can examine what you would like the software "to" do. Or at least things you think might be fun to bang out in the future, and/or use the code to do later.

    With all that in mind, you can then either start developing your own code, or look at other pieces that meet those requirements.

    Case in point: data center monitoring tools.
    Off the top of my head I can list BigBrother, BigSister, NAGIOS, NOCOL, SolarWinds, NetSaint, NetExpert, HP OpenView. If you only want to monitor hosts, all of those will do just fine. If you have more than X hosts to monitor, you start to run into issues with some of those pieces of software. Now lets say you want to do SNMP trapping/polling on network devices, some of those apps drop right out of the available list.

    So I guess what Im trying to say, is the best way I have found personally and professionally to plan the evolution of a program is to attempt to understand the problem space as thoroughly as possible. Define a base req, define what would be nice, and go from there.


    MMMMM... Chocolaty Perl Goodness.....
Re: Multilevel flexibillity
by hardburn (Abbot) on Jun 23, 2003 at 14:35 UTC

    While writing CGI::Search, I wanted to make validating CGI input a very basic part of the module (making it so integerated into it that there'd be no excuse for not doing it). As a general rule, the data would be untainted after coming out of validation (though the module itself doesn't do much that would require untainting). There were a few built-in validators, but I wanted users to be able to create their own.

    My initial thought was to pass in a regex match (via qr//). However, while regexen might be rather powerful, they just aren't good enough.

    The real solution was to pass in a referance to a subroutine. There are a few requirements that a custom validator must have (takes in the data to be validated as its only argument, returns a three-element list (a boolean value indicating success or failure, the untainted data (if successful), and a string that can be used as an error message on failure)).

    Later, I discovered the WWW::FieldValidator module. This takes things further than CGI::Search does, in that you can specify the use of either some built-in validation, a regex match, or a subroutine referance. Also, you can pass in an array ref containing mutilple validators, so that a single peice of data must mach all the validators you pass. Replacing CGI::Search's validation sementics with WWW::FieldValidator is on my TODO list.

    Finally getting to the point--like many things in software, flexibility is a more evolutionary process than something that comes in a flash of insight. Using a regex wasn't quite powerful enough, but it was simple. Subroutines were powerful, but lost much of the simplicity. The real soultion, as WWW::FieldValidator showed me, was to support both.

    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Multilevel flexibillity
by Abigail-II (Bishop) on Jun 24, 2003 at 00:03 UTC
    I don't quite agree. Generally, flexibility is a good thing to consider when writing or designing a program. But like other good things, flexibility comes with a price.

    Proper design doesn't mean you focus on one thing, and let that thing dominate all decisions. Creating a good program means finding the right trade-offs. You have to make compromises. One of the obvious prices of flexibility is simplicity. The more flexible a program is, the less simple its source code and interfaces will be. The most flexible program isn't necessarely the best program, and neither is the simplest program. Instead, the best program is the one that has found the best balance between flexibility and simplicity. And all the other things to consider: resource usage, security, maintainability, etc.

      I don't argument against design - planning the future changes of the software is a part of the desing process. I just concentrated in my meditation on this isolated part of the process.

      Perhaps the overall complexity of the flexible solution is bigger, but it is quite usuall that it means shifting the complexity to some other place and make the code simple. Once more a good example of this is templating where you don't hardcode the interface design in your program but rather leave it to some other mechanism. For complex sites your program stays much simpler that when you hardcode page generation in it.

      I think it's interesting that he considers flexibility so important. The first thing I look for is a working program. I'd say about 70% of the software I've run into doesn't completely work. Sometimes software just outright bombs (not the most common case, sometimes it flops around on the ground before it dies). Hell, I've had the gorey displeasure of having to fix a couple of programs written and abandoned by a sloppy coder.

      Sometimes I wonder how software ever even makes it past a client without being evaluated to see if it works. I've seen plenty of time and money spent on programs that don't work.

      I say, if you don't have something simple that works, then you definitely won't have something flexible/complicated that works. I've seen plenty of flexible programs that haven't worked all because somebody worried about the chrome before the engine.

      Just an opinion from a guy who's had his share of deadlines.


      PS If flexibility is so darned important, then I think no one would write one-liners.

      I don't find this an obvious trade-off.

      In fact it seems that very flexible code is often also very simple. This is particularly common when flexibility has been achieved by a modular plug-in architecture, and new features have been added through plug-ins rather than through complicating the core design. (There are, of course, significant overheads in resource usage with this approach.)

        Well, I think that proves my point. Surely code that doesn't have a plug-in architecture is less complex than code that doesn't have the additional code to deal with plug-ins. But it's also less flexible.


Re: Multilevel flexibillity
by chip (Curate) on Jun 23, 2003 at 18:44 UTC
    I would add "Protocols" -- you want protocols for inter-process communication to be flexible, easy to debug, and upward-compatible as development continues.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      I add this to externall interfaces.