Why your tiered structure might be dumb
Any class you take, any document you read… they will tell you. You need to write a three-tiered structure. You need a data access layer, you need a business logic layer, you need a presentation layer. If you put any business logic in the data layer, locusts shall devour your babies. If you put any…
Aww, crap. You’ve all heard it. It’s the same old story. It’s the same old methodology. Yes, it is getting old. This entire paradigm predates Design Patterns, and it is silly, sad and old. But let me tell you. Do you know what happens?
Weird, silly, unadvisable, sub-optimal, somewhat inefficient, odd, quaint, endearing, and oh, let’s just get down to it: STUPID things. I have now seen 6 distinct, home-grown, be-all-end-all bet-the-company three-tier frameworks, and without fail, here’s what happens:
Mip-map
Objects get mapped, abstracted and the resulting patterns never, ever get profiled. You know, the thing that would make Rico Mariani prowl the hallways with a shotgun and a quarter… buy a clue or buy some buckshot. Anyway, if you are curious what this anti-pattern looks like, here’s an example. Let’s assume you have types of widgets, and that there are properties for your widgets. Let’s say you have about 271 widgets, and about 8,700 properties on them. Now in the olden days, you would open up a recordset on all widgets, and populate your in-memory representation of them. Whether that should be a full representation or not is another matter entirely, and although quite relevant to this discussion, perhaps something to be saved for later. For now, what is important to remember that 99.99% of any and all data fits into some type of hierarchy.
In the olden days, you would do something like this:
OpenRecordSet(Select * From WidgetProperty)
While Not EOF
WidgetCollection[RecordSet.TypeOfWidget].Add(new WidgetProperty)
Of course you would optimize this. For starters, you would sort the sucker by type of widget, track what the last type of widget is… all that jazz. But one the Three Tier Mantra enters the picture, all of that gets pushed down. In good OOP fashion, you end up with
Widget : IWidget
Widget()
OpenRecordSet(Select * From Widget Where WidgetType = TypeOfWidget)
While Not EOF
MyProperties.Add(new WidgetProperty)
And, of course, to round it out:
WidgetCollection
WidgetCollection()
OpenRecordSet(Select * From Widget)
While Not EOF
This.Add(new Widget())
No, I’m not kidding. This ALWAYS, ALWAYS, ALWAYS happens. If you don’t see where this is going, if you don’t see what the problem is here… please don’t ever come to work with me. Thank you.
So, to get even more pseudo-code. Instead of:
Give me all your WidgetProperties
For each property, let me put it where it belongs
Give me all security on WidgetsProperties
For each security nugget, let me put it where it belongs
No. Too brutish. Let’s try it this way:
For each Widget, load properties.
For each Widget, load security.
See? See how that works? See how that makes things easier?
Well, yes, it does. But let’s, oh, EXPAND what actually happens.
For each Widget, load properties.
Create new Widget
Load all properties for this Widget
Check security on this Widget
If by now the bells aren’t ringing to the point of Captain Obvious boredom — well, find a different trade. What happens with applications like this? I’ve seen applications go through the top-level iteration as described above 271 times to get 8,000-ish records total. Oh, and of course, since this was a very secure application, it would request permissions on each homogenous chunk of Widgetry. Of course, that part was optimized quite a bit since the security request was a large, locally constructed request for information from 3 tables, necessitating the use if temporary tables in this ad-hoc request. Stored procedures be damned, this is so much easier to maintain.
This is precisely the reason why I feel LINQ is going to kill efficient development as we know it. On the one hand, I am beyond angry because it will put over-engineered train wrecks in my path. On the other hand, fixing said train wrecks will keep me in business forever.