Opinionated API
Recently I found myself doing a lot more API design that use the following method. A method that takes a delegate which accepts a parameter that allow you to perform the actual operations that are required.
This is very good for things like handling semantics, and since we only allow access to the desired operation through the parameter to the delegate, we can be pretty sure that we will have a consistent operation experience. Let us take the following example:
1: table.Batch(actions =>
2: {
3: actions.Put("test", new int[0], new byte[] { 1 });4: actions.Put("test", new int[0], new byte[] { 2 });5: var values = actions.Get("test");6: Assert.Equal(2, values.Length);
7:
8: Assert.Equal(1, values[0].Version);
9: Assert.Equal(new byte[] { 1 }, values[0].Data);10:
11: Assert.Equal(2, values[1].Version);
12: Assert.Equal(new byte[] { 2 }, values[1].Data);13: });
As an aside, it is 3 AM now and I have been coding almost non stop since 9AM yesterday. I hate it when I have idea rush.
Comments
When you get some sleep, can you contrast this with a conventional approach so the mere mortals can grok it?
I didn't get it...
I've actually started using this method more and more as of lately too. It's a very elegant way to handle situations where managing the "lifetime" (for lack of a better word) of the passed object could be messy in external code.
The most recent time I've used it was for updates to a thread-safe container where I didn't want to expose the locking semantics to the rest of my application.
for example (not production code, just dirty pseudo code):
container.Update(key, item => {
});
... instead of ...
lock = container.AcquireLock(key);
item = container.Get(key);
item.PropA = 'one';
item.PropB = 'two';
lock.Release();
... or ...
lock (container.SyncRoot)
{
}
The first method, the delegate one, doesn't care what type of locking the container is doing, or even if it is doing locking ... You simply tell the container what you want to do and it does it in whatever way it thinks best. In the second and third method, your code has to know how the container is going to function. In the third method, you are actively tying yourself to a locking strategy. Need to switch to a reader-writer lock later on? You need to change all your code that calls the container in the third case. In the second case, you may only need to change the container. In the first case, you would definitely only have to change the container.
Fowler has named this the "nested closure" pattern. StructureMap uses it extensively now in the registration DSL, and I've been relatively happy with it.
It's also why Roy is claiming that the OSS tools aren't VB friendly now.
Comment preview