Showing posts with label programing. Show all posts
Showing posts with label programing. Show all posts

2012/12/02

Don't write a program that does $X

A much better idea is to write a library that does $X, then write a front end program that uses that library. Your design will be better. Your program will be more flexible. Code reuse is much easier.

2012/07/29

Error messages

Continuing on my list of programming dictums that I invented over the years.

Error messages are an indication of failure on the part of the programer, not of the user.

If a user isn't supposed to do something, then the program shouldn't let him or her do it. Classic example: If you want the user to type a number, throw away any keystroke that isn't 0-9 or editing keys. Do not allow the user to type in "monday" and then throw an error message on the screen.

What's more, an error message should be short, but contain enough information for a programmer to reproduce them. In my large application at work, I save pretty much every variable I can get my hands on to a log file. I then display the log files name to the user. Users nearly always send me a screen cap of any error message they encounter (embeded in a .doc, but that's another story) so I can get the ID from there. Of course, I can also just look in the log directory for new error logs. Taking this one step further, the app could email me the ID when an error occurs.

2012/06/09

An object method may make a decision or change something

Lucs pushed me to start a small series of posts on programming dictums. I'm going to start with the one I thought up myself and post a few more as I think of them/get them written.

The first deals with OO. I do 90% of my coding in OO. In fact, one of my profs back in CEGEP commented that my assembler programs had an OO style.

So, first dictom is something I realised a few years ago: An object method may make a decision or change something.

I never quite got the hang of MVC because I couldn't understand what goes in the Controler, what goes in the Model. The answer, of course, is related to side-effects. Side-effects and decisions should not be mixed up in one method.

Ideally one should have one method per decision. If the method needs to load some data to make the decision, the loading code of course goes in a separate method. These methods may remember their decisions, but that's it as far as side effects go. I like to give these methods names like needs_barcode(), has_done_something(), is_ajax() but that's personal taste. These methods will tend to go in a Controller or be used by the Controller (if one is doing MVC, that is).

Methods that change something means any side effect: saving a file, setting a variable, munging some data. Ideally one wants to cut the side-effects up into small methods that handle related data. These methods will tend to go in a Model.

Done right, top level methods look like the following made up example.

if( $self->is_ajax ) {
    $self->output_json;
}
else {
    if( not $self->has_sent_header ) {
        $self->output_header;
    }
    $self->output_html;
    if( $self->is_streaming )
        $self->queue_next;
}

The benefits to dividing the code as I propose is when it comes to implementing sub-classes. Fine grain methods allow one to overload just the behaviour necessary, without (worse case) copying huge methods just to tweak a small part. It also makes it harder to stumble on hidden interdependencies and unintended consequences.

What's more, smaller methods are always a good thing. Small chunks are easier to stare at and prove to oneself that, yes they are doing what you intended them to do. They also improve readability, create a smaller units to build tests around and make refactoring code easier. What's more, I find that a good half of refactoring is taking large methods and cutting them up into smaller chunks.