I'm trying to figure out which would be the best API to provide to the clients of my SDK. Basically, the typical use-case would be one session instance and one renderer in one application, however, this might change in the future.
Key points: is should be easy to use from the users prospective, stable and future-proof.
Method A:
/**
* The user have to create and maintain the module
*
* pros:
* -module explicitly added at construction time
* -uses an object that would be only available using the extension
*
* cons:
* -does not enforce one-o-one relation between renderer and session
* -the burden of maintaining the module leaved to the user
* -the burden of creating the module leaved to the user
* -fixed StreamingModule implementation forever
* */
public void createSessionWithUserInstalledModule(VideoRenderer.Callbacks renderer) throws Exception {
SessionFactory factory = SessionFactory.newInstance();
StreamingModule module = new StreamingModule();
module.useRenderer(renderer);
factory.install(module);
factory.create(context, sessionCreatedCallback);
}
Method B:
/**
* A static field of the module holds the instance.
* The module will be implicitly picked up, and instantiated
* when it's on the classpath.
* It will be injected into the session during construction time.
*
* pros:
* -module doesn't need to be maintained by user
* -trivial implementation from user side
*
* cons:
* -only one renderer is possible
* -only one renderer will be available to all session instances
* -possibility of leaking the renderer instance
* */
public void createSessionWithStaticHolder(VideoRenderer.Callbacks renderer) throws Exception {
SessionFactory factory = SessionFactory.newInstance();
StreamingModule.setRenderer(renderer);
factory.create(context, sessionCreatedCallback);
}
Method C:
/**
* The module can be retrieved from the session instance, after the
* session is created.
* The module will be implicitly picked up, and instantiated
* when it's on the classpath.
* It will be injected into the session during construction time.
*
* pros:
* -StreamingModule implementation can be replaced in the future
* -session instances have their own module
* -only the session instance needed to be maintained (which is probably
* already done on the user side)
*
* cons:
* -less trivial implementation on user side
* */
public void createSessionUsingServiceStyle(final VideoRenderer.Callbacks renderer) throws Exception {
SessionFactory factory = SessionFactory.newInstance();
factory.create(context, new SessionFactory.SessionCreationCallback() {
@Override
public void onSessionCreated(Session session) {
StreamingModule module = session.getModule(StreamingModule.class);
module.useRenderer(renderer);
}
});
}
I would choose the latter solution (C), as it I see it as a golden path between the ease of use and the future scalability. Please see my comments, and advise!
I almost picked A, because it's simpler to use and the middle name of "the burden" is "flexibility".
Still, I'd go with the bastard child of A and C where there's no magic with the classpath to obtain the module.
Thoughts/reasoning: Every time I hear the words 'JVM', 'implicit' and 'classpath' in the same sentence, I lose some hair and feel like I'm being hit by a bus.
Some users may find it harder to deal with the async SessionCreationCallback compared to sequential code, but that's a really just a case of RTFM about computers.