More fun thinking aloud about MVC architectures. After reading David Hansson on "Russian doll caching", I think I'm coming around on why you'd use entities to put together piecemeal views, though I'm not sure I'm buying yet.

I'll have to find the post again, but there was one in the links I put up yesterday that said that full page caching was caching's holy grail. Compare the full page mentality to how Hansson describes the issues of caching at serious scale:

This Russian doll approach to caching means that even when content changes, you're not going to throw out the entire cache. Only the bits you need to and then you reuse the rest of the caches that are still good.

This implicitly means that you're going to have extra cost piecing together every page, even if you're just stitching cached content, and the pseudo-formula to compare to CRUD is pretty easy to stub out. If the cost of rebuilding every cache that depends on some reusable subset of those cached views' information is greater than the cost of piecing together pages from incomplete/non-monolithic cache objects on each request, then you go with the [actually fairly conventional] "Russian doll" approach.

And this largely depends on how many of your widgets appear on more than one page where some [other] subset of the content churns.

The only way we can get complex pages to take less than 50ms is to make liberal use of caching. We went about forty miles north of liberal and ended up with THE MAX. Every stand-alone piece of content is cached in Basecamp Next. The todo item, the todo lists, the block of todo lists, and the project page that includes all of it. ... To improve the likelihood that you're always going to hit a warm cache, we're reusing the cached pieces all over the place. There's one canonical template for each piece of data and we reuse that template in every spot that piece of data could appear.

Still, it's easy enough to conceive of each of these reusable chunks as embedded views, and then you're back to where you started. Pages might be Russian dolls of views (though that's the wrong metaphor beyond expressing the Herbertian concept of "views within views within views". Once you understand views can be made up of views can be made up of views, ad infinitum, you then have to remember that any number of "dolls" can live at any level, rather than the Russian dolls' one-within-one-within-one. Perhaps your main view has five "dolls" inside of it, and those have 2, 3, 0, 1, and 0 dolls inside of them, respectively, and those have...), but then so what?

If you get to the point that one of your embedded views only takes data from one table, great. I guess the only way this is useful is if the same information appears more than once on a composite page of subviews. I still think you're often getting yourself to a specialized DTO for each view, and then you should have an equally specialized Read and mapping that populates that DTO. Unless the price of querying a cache for reused information across many views is less than the price of rebuilding each cache that would be invalidated when that information changes. And that's directly dependent on the number of pages you serve between cache churns.

That is, you can call it an entity, but I think it's more useful to call it a ViewModel. Stop mapping database tables to entities. Always read exactly what you're about to put onto the page directly from the database. That's what it's there for. Really. Smart folks are working hard to optimize your queries. I realize caching makes you think you've already got the data on hand, but your hand-rolled or, worse, ORM's automatic execution plan isn't, at some point, going to be nearly as good as stating what you need in targeted SQL sent to your real rdbms.

So, and I'm perhaps overusing Atwood's micro-optimization theater post a little, without a clear winner to the "monolithic refresh vs. stitched page composition" formula a priori, what's important to me is making the system easy to support. And then, certainly, CRUD is a heck of a lot easier than SQL>>>NHib/Caching>>>Automapper>>>ORM>>>Repository>>>MVVM.

(Worth adding that I'm unfairly equating Hansson with SQL/Cache/AutoMap/ORM/Repo/MVVM (SCAORM?) here. Totally unfair; he never says he's ORMing in these posts, afaict. I think the beef here is that he's serving modular pages, and I wonder if it's worth the extra complexity short of MAX SCALE!!1! -- and even then, when you get to displaying logically disparate information, we might be saying something similar anyhow.)

That's enough thinking aloud today. Way too many tedious box-watching style chores this week, sorry.

Labels: , , ,