哪个是实现客户端的最佳方式 API
Which is the best way to implement client API
我正在尝试找出最好的 API 来提供给我的 SDK 的客户。基本上,典型的用例是一个应用程序中的一个会话实例和一个渲染器,但是,这在未来可能会改变。
要点:从用户的角度来看,应该易于使用,稳定且面向未来。
方法一:
/**
* 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);
}
方法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);
}
方法 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);
}
});
}
我会选择后一种解决方案 (C),因为我认为它是易用性和未来可扩展性之间的黄金路径。请看我的评论,多多指教!
差点选A,因为比较简单,而且"the burden"的中间名是"flexibility"。
尽管如此,我还是会选择 A 和 C 的私生子,那里没有类路径获取模块的魔法。
Thoughts/reasoning:
每次听到'JVM'、'implicit'和'classpath'这三个词出现在同一句话里,我的头发都掉了,感觉就像被公交车撞了一样。
有些用户可能会发现处理异步 SessionCreationCallback 比顺序代码更难,但这实际上只是 RTFM 关于计算机的一个例子。
我正在尝试找出最好的 API 来提供给我的 SDK 的客户。基本上,典型的用例是一个应用程序中的一个会话实例和一个渲染器,但是,这在未来可能会改变。
要点:从用户的角度来看,应该易于使用,稳定且面向未来。
方法一:
/**
* 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);
}
方法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);
}
方法 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);
}
});
}
我会选择后一种解决方案 (C),因为我认为它是易用性和未来可扩展性之间的黄金路径。请看我的评论,多多指教!
差点选A,因为比较简单,而且"the burden"的中间名是"flexibility"。
尽管如此,我还是会选择 A 和 C 的私生子,那里没有类路径获取模块的魔法。
Thoughts/reasoning: 每次听到'JVM'、'implicit'和'classpath'这三个词出现在同一句话里,我的头发都掉了,感觉就像被公交车撞了一样。
有些用户可能会发现处理异步 SessionCreationCallback 比顺序代码更难,但这实际上只是 RTFM 关于计算机的一个例子。