June 20, 2004

Programming and Information

For those of you who have been reading me for a while, you know that I've been slammed with programming work lately. One of the things that has been nice about being so busy is that I've developed some new opinions about the best way to program. I decided I'd write about it. I'm going to try to keep it on the level that non-programmers can understand. This will be a good way to see how a good programmer needs to think, and how those thinking styles can be applied to other parts of life.

Almost all of my programming has to do with the web. This is one of three main families of programming. (I'm being dreadfully simplistic and leaving a lot of things out, but it's how I'm choosing to frame it, and you'll just have to deal with it. Actually, that's kind of like programming right there!)

The first family of programming is application programming. For instance, anything you double click on to start. You interact with it, and then you click "Quit" to quit it. While you are using this program, it is always on, and always listening. When you click something, it responds instantaneously. The entire style of programming is based upon waiting for and listening to these "events". I don't do much of this kind of programming.

The second family is straight one-off programming (my term, not an academic term). You have one task you need to accomplish, you invoke the task, and then it's done. It runs once, has no interactivity, and then it's completed. I do some of this, but it's more the kind of programming that a system administrator would do.

The third family is web programming, kind of a blend of the other two. It's everything that happens when you click the Submit button, and then some. What's odd about a website is that your experience of the website might encompass several clicks, but the program you are interacting with does not run when your web browser isn't spinning. Each time you refresh a page, the program starts up, runs, and then completes and forgets everything. In order for the website to remember who you are from hit to hit (like when it knows what your username is), we the programmers have to do all sorts of complicated things involving saving little bits of information either in your browser (cookies), in a database on the website's side, or (most usually), both.

So, what I'm going to talk about is architecture. How should a programmer architect a site to make building websites easy?

Let's start with bad ways to do a website. Here's how a non-programmer sees a website's functionality.

CrazyProgram

This is a completely understandable way to visualize the workings of a website when you're not a programmer. However. Let me repeat that. This is a completely understandable way to visualize the workings of a website when you're not a programmer. Unfortunately... there are programmers that view websites this way too.

Here's how the Evil programmers do things. They start with the link, they're told it needs to do something, and it needs to end up drawing a page. So the programmer sits down, they receive the link, and they do every single little task in a step-by-step manner. Maybe the top of the page doesn't have any interactivity, so they'll just draw the html there. Then it needs to display the member's username. So they'll query the database for the username, and then they'll print it out. Then they'll load a couple of graphics, then they'll do a couple more database queries, etc.

Multiply that by twenty pages for a small website. And now let's demonstrate why these programmers are Evil, and why they also usually tend to have poor social graces, and why they hate project managers.

Pierre sashayed into the room, dashing as always. He adjusted his cufflinks and gingerly approached Rufus, who was rolling rubber cement into tiny little balls and throwing them at the secretary's hair.

"I say, Rufus?" asked Pierre brightly.

"What." Rufus glowered up at Pierre. It wasn't a query, it was a statement.

"I wanted to tell you what an excellent job you did on the website project! We were only two weeks late. True, it was initially estimated as a one-week project, but - "

Rufus snarled. "That was your fault for not telling me about the..."

"Quite right! Quite right!" A bead of sweat broke out on Pierre's forehead, which he immediately blotted with his monogrammed handkerchief. "But the site is delivered now, and the client is happy, and you did a wonderful job."

"Yes." Rufus didn't even bother to nod.

"The client did have one question. At the bottom of each page, where you list out the user's current five favorite cds? The client originally wanted each cd to show the user's rating of the cd as well - "

"WHAT?! No one told me that!" Rufus' nostrils quivered.

"Oh, I'm sure it was in the spec, I have it right here in version 2. At any rate, it seemed like a minor change, can you do that before you leave?"

"NO, I can't do it before I leave! Pierre, I can't be expected to do these large changes at the drop of the hat. I swear, I am surprised this company hasn't gone out of business yet, when people like you are the ones making promises to the client. Your mouth is writing checks that your brain can't cash, Pierre. Do you even UNDERSTAND what a large site this is? Those cd listings are on EVERY SINGLE PAGE. I have to go through every page of the website, look up the rating of the database for each song, and write it out. Can you count, Pierre? That's twenty pages times five cds. What's twenty times five, Pierre?!"

Poor Pierre. His handkerchief was probably soaked by the end of that tirade. Who's wrong in this scenario?

I drew it broadly so it should be obvious that Rufus is wrong. Rufus also has some other things seriously wrong with him, as well, but that's beside the point and I'm not sure how those qualities snuck in there. Hmm. Anyway, thank God Pierre didn't tell Rufus that the site also needed to be translated to Spanish!

When programming, it is important to take common functionality out, and create subroutines out of it that several places can call. This is Programming 101, even bad programmers know how to do this. But it is interesting that a lot of programmers stop there, and do not apply the same style of thinking to architecture and processes.

On a very abstract level, every interactive website goes through one flow pattern:

  1. It retrieves information
  2. It does stuff to and with that information
  3. It displays some information
Here is another way to look at it:
MVCProgram
Here's one more way to look at it. There's stuff. There's stuff that you do with that stuff, and then there's how you make the stuff look.

Sometimes I like looking at it as nouns, verbs, and adjectives. In any program, you are going to have things like Members, or Customers, or Products, or CDs, or Articles, or WeblogEntries, or Recipes, or Activities, or whatever. These are nouns. If you've got a website that has to do with customers buying cds, you are going to have Customers and you are going to have CDs, and that reality just isn't going to change very much.

What is going to change is what you do with them. Sometimes you might want the Customer to have a new CD. Or you might want them to rate it, or buy it, or destroy it, or compare two cds, or trade them with another customer. These actions are limited only by the imagination of Pierre. These are verbs. They are constantly in motion, always changing, and Pierre needs his change fast.

Finally, once you have the customers collected and the cds rated, you need to show the page. You've got all the information loaded up, the processing is done. All that's left is deciding how to make it pretty. There's no real functionality here, it's just dressing. These are the adjectives.

This is why it's very important to keep these three layers separate. Nouns don't change very much. A customer might get a middle name, but he's not going to turn into a llama. Verbs change all the time - there are always new features. And the adjectives can change even when the features don't. What if Pierre wants everything to be exactly the same, but he wants it in a lighter shade of blue? Or, in Spanish? They are still customers, they are still cds, and the features are the same - it's just in Spanish now. It shouldn't be necessary to reprogram the site. Just drop in the translation.

If you need to change the display, you don't want to touch the featureset. If you need to change how a feature works, you don't want to touch how the data is stored. This is how bugs happen. This is why Rufus is a rude creep, because he didn't think ahead. He knows his abilities are poor, but he's not taking responsibility, so he bullies others into thinking the flaw is on their side. He might be President someday, but he's not a good programmer.

Well, I haven't really gotten into the stuff that I've learned for myself recently (which has to do with finding the right mix between OO inheritance and standard MVC encapsulation), but this is a good stopping point. I hope this was interesting, and I hope you never have to pick rubber cement balls out of your hair.

Posted by Curt at June 20, 2004 01:04 AM