When you sit down to write a program, there are tons of different ways you can go about it. The "best" way doesn't exist. Sometimes it's driven by how many people will be using the program, or how quickly it has to be written, or how much money is supposed to be spent writing it.
But sometimes none of that comes into play because of the standards established by the company you're working for. In that sort of environment, you do what you have to do, regardless of any other factors.
Today I've been beating a program into submission under my company's "n-tier architecture" policy. It's driving me mad!
Basically, each "tier" -- or "layer" -- of an application is broken apart and made separate from every other. (N-tier just means "multiple tiers") So the layer that talks to the user (the screen display, for instance) is wholly separate from the piece that decides if the data entered by the user is acceptable. (The "business rules" layer) These two are separated from the layer that manipulates the database, storing and retrieving the data. (The "data layer"). ('Wholly separate' might not be quite accurate, but the point is that I can yank out and completely overhaul one layer without disturbing the others.)
There are good reasons for doing this. One is security. The user -- no matter how hacker-sharp he is -- can't find anything in the screen display or underlying code that tells him how to get to the database. (Though of course it could help him find the business layer, which leads into the database...)
Another plus is that if you decide to put a different display on an application (like a handheld display, or a telephone-based interface), the only layer you have to change (theoretically) is the display layer. The other layers remain unchanged.
Those plusses are more-or-less real.
But they come at an incredible development cost. For instance, my boss said he'd like me to add a "Would you like to be contacted about this issue?" field to the screen, with a yes/no option. Single field in the database, single field on the screen. Should be easy, right?
Here are the steps I went through to accomplish this:
- Create field in database.
- Modify stored procedure in database that inserts new record in table; add field.
- Modify stored procedure that updates existing record; add field.
- Modify stored procedure that retrieves record; add field
- (test all stored procedures by hand)
- Modify VisualBasic Component class that handles this record, add variable to hold the value of the field.
- Modify class, add "get" method for this variable
- Modify class, add "set" method for this variable
- Modify class, modify method that saves record to send the value of the variable to the database when it calls the previously modified stored procedure.
- Modify class, modify method that updates the record
- Modify class, modify method that retrieves the record
- Modify Display layer, add field to the "new record" screen
- modify display, add field to the "update record" screen
- modify display code, add call to "set" method on "new record"
- modify display code, add call to "set" method on "update record"
- modify display code, add call to "get" method on "update record"
- (test display and business layers together because I couldn't bring myself to write a script to test just the business layer)
(I should note that this application is itself not written terribly well, the "new" and "update" should really be in the same program, rather than two separate ones. I inherited this code, and it's not worth merging them now.)
Believe it or not, it gets worse. Rather than simply registering the DLL's on the web server, we run them as COM+ Applications. (To allow the web server to be on one machine and the COM calls to be shuttled over to some other machine.) So whenever I make a change to the COM layer (which is every 5-10 minutes for about 3 hours while I'm working on it) I have to:
Unload the web application (to get it to release the DLL)
- Delete the COM+ application
- Compile the DLL
- Recreate the COM+ application
- Drop the DLL into the application to show it the methods available
Then I run a test. And it fails. So I dig around, try something else, and repeat the above process. It's absolutely mind-numbing!!!
Especially because it is SO UNNECCESSARY!!!
Any purist that wants to leap in here and tell me that it's developers like me that make lousy applications that are hard to pull apart later, and that can't be split over multiple machines, and yada yada, go right ahead. It won't matter, I HAVE to do it this way anyway. But I'll never agree it's a good idea. (Not applied across the board, to every damn app in the enterprise, anyway.) The time it takes to write one of these n-tier apps could easily write the same thing twice without it. Probably thrice. So if you build 2 applications without it, and that forces you to completely rewrite one of them to handle some new display or database or whatever, you're still money ahead. And in my experience, that next-to-never happens. You 'keep the door open' for whatever changes they think they might want to make, then they never make them. It's like having a trunk full of spare tires for cars you don't own -- just in case.
Not only does all of this take a ridiculous amount of time to code, but it adds complexity to the program. Complexity always means more bugs, and a steeper learning curve for the next poor fool that has to work on the code. I try to be helpful and name all the related variables the same. The field in the database, the variable, the set/get methods, the field in the HTML form, the javascript variable that holds the value for client-side validation -- they're all named the same. That helps, but there's just so MANY of them. Sheesh!
(And of course, you have to factor in the time it takes to go online and rant and rave about it.)
There. I got it out. Thank you for letting me take up a spot of your time to holler at this stuff! I do feel a touch better.
Dave