Justin has a post called: Keep your IQueryable in check, in which he basically says that while he finds value in the Query Object pattern that I recently talked about, he is concerned by the fact that I am returning an IQueryable (or ICriteria or IQuery) from the query object. The problem is that the UI layer can then modify the query in potentially undesirable ways. The example that he gave is:
latePayingCustomQuery .Where(c => c.LastName.StartsWith("E")) .Skip((page - 1) * itemCount) .Take(10);
Which perform a query on an unindex string column, which is slow.
He suggests limiting what the user can do by providing a IPagable && ISortable that would limit the options of the UI layer to abuse it.
My response to that is: And…?
I am not in favor of doing things to protect developers, but there is also another side to that.
What is the worst thing that can possibly happen? That part of the application would be slow. We will find it during testing, or (heaven forbid), on production.
How is this in any way different than anything else that we are doing? Presumably the developer who wrote the code didn’t wrote it just because he felt like it, there was a business reason behind it. At that point, we treat this issue as a standard perf issue, and fix it.
The cost of doing that in the rare cases where it will happen vs. the cost of creating the limited abstraction, forcing developers to deal with that, etc. More than that, I can assure you that you will need to break out of the straightjacket at some point, why put it on in the first place?
This is a question that I routinely ask my clients. Why do you want that? “To stop developers from…”
To which I reply: “What is the cost of doing it this way? What is the cost of a mistake? What is the cost of fixing that mistake? What is the difference between that and just another bug?”
There is a reason that I choose the ALT.Net logo to be running with scissors. Power tools are here to be used. Yes, there are things that you want to hide, but those are by far the exception, not the norm.