At Oren's suggestion I spent a few minutes today considering whether the Patterns & Practices Caching Application Block would be a good fit for a couple of my applications. It seemed quite powerful. I found myself admiring the abstract structures and some of the design ideas even though I wasn't sure I liked some of the dependencies. Still, I found myself feeling unaccountably lost. Why was it so difficult to decide whether and how to integrate these components?
Then it dawned on me. I was focusing on accidental properties of the problem. While sifting through this foreign code base I'd lost track of the essential problem I was trying to solve: caching. I wanted a simple caching service that I could plug into my applications with a rudimentary common case implementation and the option of swapping in fancier ones for certain deployment scenarios and for testing.
The P&P CAB components went well beyond solving the essential problem: they were codifying a solution! They provided a rigid framework with extension points for backing stores, instrumentation and other odds and ends. They designed it as if they thought they had solved the caching problem so well that no one else could ever quibble over the implementation.
The telling sign is that the central components were not designed as services. There was no ICache interface to be found anywhere, just a Cache class with many assumptions and pieces baked in and some half-hearted ICacheOperations interface. I was instantly reminded of all of the things that I dislike about frameworks...
I'm not in the market for frameworks! I want services I can use and choose to extend or reimplement as I see fit. (That's why I like the Castle Project so much.) For my caching needs all I want are some components that implement a little service like this:
public interface ICache { bool ContainsKey(string key); object GetValue(string key); void SetValue(string key, object value); void Flush(); // and maybe a few other things... }
So after all that, this is what I finally wrote in the Castle Developers mailing list to sum up my observations:
Trouble is it's [P&P CAB is] so far out in YAGNI-land for me that I don't know what to do with it!
4 comments:
Well said Jeff! I think the accidental/essential distinction underlies much of this debate. It's a distinction that deserves to be discussed more. I often hear "Product X is good because it lets us do A, B and C" - where A, B and C are _all_ accidental properties of the solution (or very often, accidental properties of Product X itself!)
OK, so what did you settle upon instead? Thanks!
@Anonymous,
It's now called Castle.Components.Caching. But it's nothing special really. You can find the code in the Castle Contrib branch here: https://svn.castleproject.org/svn/castlecontrib/caching/trunk/
It’s true that along with many benefits CAB has many problems as well and some of them have been discussed in your article. Once I happened to use CAB and I realized that it can perform well in small configurations but for larger distributed applications, it starts giving you scalability and integrity problems. Here's a good read about the limitations of Caching Application Block.
Post a Comment