[Chicago-talk] A question of design

Jim Thomason jthomasoniii at yahoo.com
Thu Feb 12 11:34:02 CST 2004


Okay, in my free time for the last week or so, I've
been designing and building a generic state machine
(DFSA, I'm not that much of a masochist). POE inspired
me to run off and do it, so blame Jonathan. :*)

Basically, everything on my site (and lunchmanager,
for those of you signed up for it) is pure MVC. Now, I
like my model (modules talking to the database), it's
fairly robust and well built. I like my view (the
templates I use), because all the presentation is
there (although, admittedly, I have a bit more program
logic in there than I really should in places). But my
controllers (the CGIs in between) I've never been
happy with. For one thing, they largely do the same
abstract thing (load an object, display it, modify it
if necessary). It boils down to this:

+-------+      +------------+    +---------+
|       |      |            |    |         |
| Login Y------> Returning? N--+ | Display |
|       |      |            |  +-> object  |
+---N---+      +---Y--------+    |         |
    |              |             +---^-----+
+---V--------+     +----+            |
|            |      +---V---------+  |
| Fail       <---+  |             |  |
|            |   +--N Authorized? |  |
+---^--------+      |             |  |
    |               +---Y---------+  |
    |                   |            |
    |               +---V---------+  |
    |               |             |  |
    |               | Edit object |  |
    |               |             |  |
    |               +---V---------+  |
    |                   |            |
    |               +---V---------+  |
    |               |             |  |
    +---------------N Success?    Y--+
                    |             |
                    +-------------+

(My apologies to those not using a fixed width mail
client. And man, I have *really* gotta update
Text::Flowchart. I haven't touched that thing in 4
years. Still faster using it than it would've been to
draw that by hand)

Now, naturally, the individual pieces are radically
different (again, using the lunch manager, storing a
user is completely different than storing a meal or a
proposal). Different methods, different validation
checks, etc. Nonetheless, it's conceptually the same,
so I've been gnawing at it trying to genericize it. I
don't like having similar chains of mostly
hard-to-read if/else/error ladders as the basis of my
CGIs.

So I've been designing machines. The present result is
this machine implementation which does what I want.
For example, say there's a screen that edits a user.
Requires name, username, and password, nothing fancy.
That's easily done with a new CGI machine:

my $machine = JIM::Machine->new(
        'type' => 'cgi',#JIM::Machine does have
abstract factory ability
        'parameters' => [qw(name username password)],
        'validTemplate' => 'success.tpl',
        'invalidTemplate' => 'failure.tpl',
        'message' => 'Success! User updated',
        'states' => {
        	'creation' => sub {
        		my $machine = shift;
        		my $user = JIM::User->load($username)
        			|| JIM::User->new();
        		$machine->heap('user', $user);
        	}
        }
) || die JIM::Machine->error();

$machine->run();

Voila. That loads the parameters, validates them,
commits the object, and redirects the user as
appropriate, with a useful message of some sort.
You'll also note that the 'creation' state of the
machine is overridden with the logic specific to this
machine instance (namely, how to create a user object)
(yes, states that can/should be overridden are
documented in the module). I debate genericizing that
step as well, but I don't know if I want to implement
an abstract factory in my root class.

But I digress.

It does gloss over some of the steps (such as
permissions), but the gyst is there and I didn't want
to bog down with too big an example.

Does this seem sound to you guys? I'm trying to
convince myself that it's close to the decorator
pattern (http://wiki.slowass.net/?DecoratorPattern),
but I have a nagging suspicion that it's closer to a
MixIn (http://wiki.slowass.net/?MixIns). I'm leaning
more and more towards it being a decorater, but I just
haven't convinced myself.

So what do you guys think? Sound like good design or
bad? Probably tomorrow I'm going to start re-factoring
the Lunch Manager to use machines like this, since
that's going to be my test case to see how easy and/or
feasible this approach is in practice. But suggestions
about theory would still be welcome. If somebody looks
at it and says, "Ah ha! That will bite you in the ass
because of *mumble mumble*" it'll invariably save me
some headaches.

-Jim....

__________________________________
Do you Yahoo!?
Yahoo! Finance: Get your refund fast by filing online.
http://taxes.yahoo.com/filing.html



More information about the Chicago-talk mailing list