Quote:
Originally Posted by Neil S
Well, see, to me when I read that, my fear as a user would be that if you aren't really good at defining your interfaces right the first time, then I as a user will have to rewrite my scripts with every new version, because they will have to be revised to work with your new, nittily-defined, static-bound interfaces.
And well maybe you're a wizard, know your problem space intimately well, and will get your script interface perfectly the first time.
But the more loosely you force the user to deal with your own private types and handles, the easier it will be on your users going forward.
As I indicated, my users are not programmers. Sometimes they'll borrow programmers for a very limited time. Sometimes we'll write their scripts as part of the installation. Sometimes they muddle through with the only programming they've done in a decade.
So the incetives are really strong to make pain fall on me instead of them.
Let's toss out the notion that I can define the interface perfectly. Successful software always obsoletes itself, so if there are no changes needed then I've failed.
So how to handle changes? I don't see staticly typed interfaces as an obstacle at all. Nor do I see late binding as helping with versioning problems.
My default approach is to treat interfaces as immutable contracts. Changes are new contracts that mean new interfaces -- implementing multiple interfaces per object. So we start with IFoo, then offer new / better IFoo2, IFoo3, ...
Clients get the interface they understand -- they ask for the IFooN they like. New or different functionality doesn't cause them any pain. I have the responsibility to make sure the old interfaces remain supported, but I think I have enough indirection to do that.
---
With late binding there needs to be an explicit version negotiation built in to the API. Otherwise, what do you do when the meaning of a method has changed, but not its signature?
Keeping my private types and handles from the user is good sense either way. The object model the user sees is one that makes sense from their POV, there is a proxy step that maps that to the internal objects.