Different programming worlds
I have had this article in my head for almost a year but reading Practical API design book have forced me to finally write it. The idea is not new or revolutionary, on the contrary it's quite obvious: There are different programming worlds. We can use metaphor of workshops.
Jaroslav Tulach, author of Practical API design book works in one workshop. He is creating components for other programmers. Lets imagine that he is making nuts and bolts. Of course, his nuts and bolts are more sophisticated, but for sake of argument lets imagine this simple nuts and bolts scenario.
Apparently, his customers are other craftsman and their main requirement is compatibility. They want to use his parts in existing machines, they want to use the same tools they currently have. He just can't decide, that hexagonal head is not modern any more. All his customers have tools for them. Therefore, he has too maintain compatibility. Of course, in some cases he can enhance quality by using better materials, he can introduce better types of components, but once a component is sold to a customer he can't change its dimensions or other important properties. For him backward compatibility and well defined API are crucial. I think that definition for API should be: “Something that is not allowed to change”.
I am on the other hand server-side Java programmer. I write software mainly for end-users. Lets say that I am building custom-made bicycles. You know, some people have so special requirements that they can't go to a shop and just buy a bike. They need special, super-duper tailor made bike.
Usually they do not care what parts I use. They want me to meet their requirements and do it as fast as possible. In this case, I don't care about API at all. I just take existing components and put them together. Of course, I want this components to be well supported, developed in backward compatible way. But me personally, I do not care about creating APIs. I am just using them. Sure, I create my own components, but I do it only because I have to. Sometimes I have to connect two incompatible parts, sometimes there is no-one who makes the part I need. But I always prefer to use already existing parts. I do not know how in bike workshop, but in software there usually is no need to write your own library or new API. Of course, sometimes you are doing something really revolutionary, sometimes your customer requirements are really special, but in my experience, usually customers want something that has already been done hundred times before and there is already someone who makes corresponding parts.
There are only two cases when we have to define an API. The first one is, when we want to reuse custom made components in different projects. It looks like a plausible argument, but I think that in 99% of cases there already is an existing library that already does almost exactly what you need. And I think it is always better to use existing solution then reinvent a wheel.
The other situation where you have to define an API is when you interface with other supplier. For example if your customer wants to mount a rocket launcher on the bike. Then you usually have to agree on some interface between you and the rocket launcher manufacturer. I would bet that there is already a standard for this, but if there is no standard you have to define an API. In my workshop it is usually done using WebServices or other XML based format just because it is easier to change such API in almost compatible way. I usually do not use Java based API just because all the versioning and other issues it brings.
Well, it looks like I do not do anything useful. Hell, I have to defend myself. My added value is that I put those parts together. Customers do not pay me for making bicycle components they pay me for delivering a tandem-tricycles for elephants. That's my job. To build such thing as fast as possible and as cheep as possible. They do not want me to loose their money by reinventing a wheel.
So in my case creating an API is not useful. Sometimes it is even harmful. I'd like to be flexible, I want to be able to fix my mistakes as fast as possible, I'd like to change my design quite often, I do not want to maintain backward compatibility. I do not have to. The only people who will be influenced by my changes are my colleagues. It is quite easy to fix their components accordingly to my changes. At least in software world.
Of course that I try to create well encapsulated and reusable classes. Of course I try to create some kind of communication interface to all my modules. Even for internal usage, I like to have some level of cluelessness. But I would not call it API. It is something one level under API. For me it is just an implementation trick I use to make my life easier. I am not publishing it outside the team, I know that it is not stable at all. It's not an API it's just PI. Of course the distinction is not clear, but I still feel that there is a difference between a stable API and volatile internal PI. Both of them hide implementation details but only API has to be stable.
There are other types of workshops as well. There are for example mass producers. They sell bikes or software in boxes. These people live somewhere in between. They try to use existing parts as much as possible, but they have to differ somehow from their competitors. So they have to provide something special. In this case, there might be a reason to create a special component and make it standard, so they can share this component between teems working on different products. But again, I do not think that they need stable well defined API so much.
There are of course other types of workshops, but my metaphor is slowly reaching its limits so I will abandon it. What I want to say is, that there is no one size fits all approach or advice. What a surprise!
For example, you can read that you should not optimize your code because JVM will do it for you. That's true unless you work for mobile devices. I recommend you to read this, it goes against everything I believe in, yet in their use case it's valid.
There are other examples, I am sure you will come up with your own. The important thing to realize is that there are different worlds for which different approaches apply. So if you do not agree with someone, maybe the reason is that he is from completely different world.