The sad thing here is that late binding seems to offer better user experience by allowing bug fixes to be propagated with less resistance on the one hand, but then introduces new problems on the other hand that can seriously impact user experience. Somewhere, there, a tradeoff needs to be made.
And if you’re thinking that this tradeoff is purely hypothetical, think again. Let’s go back to dynamically linked libraries by way of explanation, and briefly examine how different operating systems handle different versions of the same interface/library.
- On Linux and Solaris, it’s possible to specify interface versions for dynamically linked libraries. Ulrich Drepper has an excellent paper on Good Practices in Library Design, Implementation, and Maintenance that discuss this mechanism, amongst other things.
- On top or in parallel of the above, Linux systems employ sophisticated package management to ensure that dependencies are resolved at installation time. RPM for example parses dynamically linked libraries for their interface versions, and marks packages as either providing or requiring these interface versions accordingly.
- On Mac OS X, there is a Framework directory structure that lets you handle different versions of the same library. Interestingly, few libraries I’ve seen use that. The related app bundle structure also lets you place frameworks special directories that the operating system will search first when resolving dependencies, which essentially reverts the whole thing back to a form of early binding.
- Windows systems infamously suffer from DLL hell
.
There will be a plethora of other approaches to handling dependencies on interface versions, but those give a decent overview of the choices: in a strictly managed system, then, you can have all the benefits of late binding. In less strictly managed systems, you either give up on some of these benefits (e.g. OS X Frameworks), or cannot guarantee a reasonably smooth user experience.
Those appear to be the choices.
After this rather lengthy excursion into libraries/interfaces and how to approach managing them, let’s go back to Android and Intents. No, I haven’t forgotten about them — I hope you didn’t either.
In Android, an Intent is — from a certain perspective — a name under which functionality is bundled. By passing that name to the operating system, you expect the operating system to invoke such programs that implement the desired functionality. While there are strong differences to shared libraries and dynamic libraries in this, the difference to plugins or services becomes a lot more blurred.
Intents, just like plugins and services, are late bound. That implies all the same things: the program using an Intent must handle situations in which the dependency can’t be resolved gracefully. It also means you can’t guarantee your program will always perform all the desired work without requiring additional software to be installed. From the end-user’s perspective, then, there are no discernible differences between using Intents and plugins or services to re-use code.
So you’re left with two choices to mitigate these issues: either trust the developer of each program to handle these issues gracefully, or provide some operating system level way of managing dependencies.
The first, in my experience, does not work very well. Developers are quite often too technical-minded a bunch to realize how difficult it is for people like my mum to deal with problems arising from unresolved dependencies. From the perspective of end-user experience, there is nothing better than static linking, for all the lack of elegance that implies.
As for the second, the systems that have dealt with the issue best end up being those with a very strict install-time management of dependencies, such as most of the Linux distributions out there. It seems obvious to me to look to those as a model for keeping some of the benefits of late binding, while simultaneously providing excellent user experience.
There is an additional benefit to an install-time handling of dependencies over early binding, and that is that it’s entirely possible to install multiple software packages that provide the same interface. It then becomes possible to let the user choose which of these packages they prefer at run-time. I like that. It’s a clear argument for late binding, in my book. But it doesn’t help the fact that late binding can seriously impact user experience, if it’s not handled well.
Now I just need to (help) write software that does that “handling” for Android and Intents, it seems…
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_c.png?x-id=c8579a9e-4f7e-4440-b1c3-c28eb4e1b35c)

