Hinges and Screws
At the end of the XIX century, a screw company called Stanley started selling hinges, and quickly became the largest hinge maker in the market.
Their hinges were almost the same as any other, the hinges were a mature technology, they had no price advantage, no hinge-making experience, and no manufacturing difference with the competition.
How did they do it? They packaged the screws along with the hinges. Since anyone who bought a hinge needed the screws anyway, they sold more product, and the buyer was happy because he didn´t need to find matching screws.
There´s an obvious lesson there: If the consumer always needs two products at the same time, they are not two products, they are one, and selling them together should make sense.
How can we apply that (now) obvious lesson to software developement, and open development in particular?
I think the easiest place is for the platform maker, for example, the guys who make the base KDE or GNOME environments.
Since I am more familiar with KDE, and I think it is approaching this mostly right, I will use it for the rest of the article.
Example 1: Network access
As everyone probably knows, KDE provides a base technology called KIOSlaves, which lets any application using the framework (and coming soon, any app) access files accross networks using a diversity of protocols in a transparent fashion.
For example, if you want to open a file on a remote server that has SFTP access enabled (almost every Linux box comes with it), you just open sftp://the.remote.box and go from there, transparently.
Why is this an example of integration: Users don´t want a product to edit files and a product to fetch remote files. They want a product to edit local and remote files.
Hell, they want a prouct to edit files, and that´s it, they want hinges.
By putting KIOSlaves in the base platform, KDE unifies the traditional products (application + sftp/ftp/DAV/whatever client). After all, when is the user going to need fetching a file he is not going to open? Rarely ever, and that is covered by integrating the KIOSlaves into the file manager, using the same principle.
So, KDE is actually integrating the remote file access in such a way that it is bundled with every KDE app. That is a good approach.
Example 2: Addressbook
Here, the screw is the addressbook.
People don´t buy screws for screwing´ sake, they buy them to screw stuff to other stuff.
While a separate addressbook application makes sense for the occasional session of batch adding or removing contacts, that is not really the main use. People get email and want to add its sender to the addressbook, or fail to contact someone via IM and want to send email to that same guy quickly.
How should that be done? Probably by having the email and IM apps access the same database, and context menus on all person information, is my guess.
For those things, addresbook-as-a-service is what you need. In this aspect, KDE´s integration of its addressbook is not quite perfect (I am on vacation, I can´t check it, feel free to correct me), but for example Kopete, the multiprotocol IM app is rumoured to be integrating it further.
Other examples are easy to find, where a feature that is not application-specific is factored into a base library and recommended for each app that needs it.
But those are not the only cases. You should also consider widgets, like the khtml library. But I am not trying to just say the tired mantra of factoring into libraries.
Just because it is into a library it doesn´t mean that it will be usefully used. This is more a policy thing: useful things are put into the platform libraries and you are supposed to use them. Don´t create your own toolbar handling code using Qt: just create a toolbar. Then it´s editable, and it follows the L&F, and so on. Platform code, not your code.
That, while obvious, is cutting against the nature of the open source developer, who likes to code... if you can just use the class library, it´s not quite as challenging.
But... it can be done, as KDE shows. KDE obtains its uniformity not from written or enforced guidelines (although they exist), but by default: If the stuff in the platform is good enough and easy enough, and everyone else uses it, you end using it too.
So, the hinge/screw rules would be, as I see them:
- If it is needed in several apps, factor it out
- make it easy to use, or noone will
- make it good before you put it into the platform, or you will get variants, and effort is wasted
- convince people that their life is easier if they exploit the platform. The Perl and Python community do this brilliantly.
- the API matters
- each component should be fairly independent of the others.
As the platform becomes deeper, application writing becomes easier, so application developers can tackle harder problems, which will, eventually, enhance the platform.
That is the virtuous circle of tighter integration, and it´s usually a good thing, as long as you don´t tangle all components to each other: wide platform is good, monolithic platform is not so good.
This is an ongoing process. The platform grows all the time, and application developers are the molding force behind it. Create cool apps with interesting components, and try to keep the components modular enough that they can become platform pieces later.
If there is something in the app you wrote or use that would seem a natural fit for another app, contact the authors, maybe they didn´t think of it, or don´t know that work, or just deemed it too hard to attempt, while someone else already did it!.
Stanley Works had assets for 2418 million dollars as of December 2002.