Zero Friction and why Defaults Matters
Several times recently I had to answer why I care so much for defaults if they are something that I can change. My answer is usually a derivative of "defaults matters". I have come to understand that this is not a sufficient answer and I need to clarify it.
I have talked extensively about Zero Friction environment and why I care so much about it. It is about how much I have to fight the tools that I have in order to get what I want.
I spent much of yesterday moving Rhino Tools from MsBuild to NAnt, because MsBuild doesn't have any way to get the current framework version. That is a big task, and considering that I can add this functionality to MsBuild in a few minutes, why did I do that?
Again, it had to do with the fact that when I need a solution, I had to work hard for it. With NAnt, it is just there. For most of everything, in NAnt, it is just there. Between the two, NAnt is the tool with less friction. In the long run, this mean that I would be able to work more efficiently.
How does this related to defaults? Well, consider this, if I have to extend / change something to get something that I consider a baseline functionality, this is a problem. This is friction, and if it generating that much friction early on, I can safely assume that it will generate much more friction when I want to do the advance stuff.
At that point, thanks but no thanks.
To put it in more familiar terms, whatever defaults you have are the Out Of The Box Experience that you have for your software. If you missed the default, it is as if you just hand me a product in one of those ugly and hard plastic shell (the ones that you need scissors just to open) and told me that I can put it in a pretty designer box.
Yes, I can, but you missed your chance to get me.
And that is ignoring the fact that default, for most people, are what is happening. You need good defaults.
Comments
What if what you consider to be 'baseline functionality' or a 'good default' isn't what someone else considers them to be?
I'm not suggesting it is totally capricious, but I think a lot of what really amounts to personal preference is often mislabelled 'good'.
Jdn,
I do believe that I am capable of distinguishing between personal preferences and design issues.
Where appropriate, I try to make that clear.
That said, unless there are some really good reasons for those defaults, they get the same treatment. A lot of what I would consider personal preference is part and parcel of the way I am working. And that is damn important.
Of course you are, that isn't in question, but design issues are rarely if ever one-sided, one answer fits all issues, so it isn't an either-or proposition.
This isn't a comment about you in particular, but something I've noticed a lot in the alt.net mailing lists, the lack of understanding here.
It's hard to come up with good defaults in design, especially when design is literally design (by which I mean UI). I think it is also probably true in code.
It's quite possible that NAnt did not come with the possibility to query for the framework (maybe it did, but that's besides the point: I am sure there are other examples). Someone has build it for NAnt, as you had the opportunity to do for MSBuild at this point. You choose not to do so, which is understandable, but someone did do that for NAnt. It seems unfair to judge a young product based on the amount of community contributions.
However, it is fair to chose one product over another because of community contributions. But just be clear about it.
MSBuild's building its filesets at startup is what caused me to switch to Nant. Having to go through some awkward syntax to do something as simple as moving some files that you generated during the build into a zip file is ridiculous and just doesn't make any sense. Its easy in Nant.
Oh, yeah. That one was PITA.
hehe, and there you have a good reason indeed. It's ridiculous ;-(
This is the main problem I have with Castle IoC -- bad support for things I consider to be a baseline.
These are:
An easy way to resolve all dependencies as mocks (and API to do it manually is quite cryptic, though I won over it).
An IEnumerable<T>/List<T>/T[] resolution with logic same as ResolveServices<T> (same API, and also I ended up calling ResolveServices<> from non-generic code -- no fun at all)
An easily discoverable version of BatchRegistrationFacility that can find internal classes (at least that's easy with Linq).
This also demonstrates that such baseline requirements are indeed subjective, since Castle guys haven't implemented them yet (and I consider lists requirement essential).
Andrey,
1/ That is why we have the Auto Mocking Container. An extension to Windsor that does just that.
2/ container.ResolveAll() have both generic and non generic implementations.
3/ That is something that you can write yourself in about half an hour.
Comment preview