IAm*_*aja 9 java api design-patterns slf4j
我正在创建一个框架,公开API供开发人员使用:
public interface MyAPI {
public void doSomeStuff();
public int getWidgets(boolean hasRun);
}
Run Code Online (Sandbox Code Playgroud)
所有开发人员都应该做的是根据这些API方法编写项目代码.我还希望他们能够在运行时类路径上放置不同的"驱动程序"/"API绑定"(与JDBC或SLF4J的工作方式相同),并让API方法调用(doSomeStuff()等)在不同的第三方资源上运行(文件) ,服务器,等等).因此,相同的代码和API调用将映射到操作上的不同资源,这取决于驱动器/绑定运行时类路径看(即myapi-ftp,myapi-ssh,myapi-teleportation).
我怎样写(和封装)的SPI允许这样的运行时绑定,并再映射MyAPI调用正确的(混凝土)执行?换句话说,如果myapi-ftp允许你getWidgets(boolean)从FTP服务器,我怎么能这样(使用API和SPI)?
具体的工作Java代码示例的奖励点!提前致谢!
Mat*_*att 16
看一下java.util.ServiceLoader类.
一般来说,这个想法是这样的:
API Jar
绑定/驱动程序罐
在javadocs中有一个很好的例子:
http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
package com.foo;
public interface FooInterface { ... }
public class FooInterfaceFactory {
public static FooInterface newFooInstance() {
ServiceLoader<FooInterface> loader = ServiceLoader.load(FooInterface.class);
Iterator<FooInterface> it = loader.iterator();
// pick one of the provided implementations and return it.
}
Run Code Online (Sandbox Code Playgroud)
package com.myfoo;
public class MyFooImpl implements FooInterface { ... }
META-INF/com.foo.FooInterface
com.myfoo.MyFooImpl
Run Code Online (Sandbox Code Playgroud)
编辑
public interface FooSpi {
void accepts(String url);
FooInterface getFooInstance();
}
public class FooInterfaceFactory {
public static FooInterface getFooInterfaceInstance(String url) {
ServiceLoader<FooSpi> loader = ServiceLoader.load(FooSpi.class);
Iterator<FooSpi> it = loader.iterator();
while (it.hasNext()) {
FooSpi fooSpi = it.next();
if (fooSpi .accepts(url)) {
return fooSpi.getFooInstance();
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
当然,将文件名更改为com.foo.FooSpi并提供FooSpi的实现.这将允许您将公共API与Spi接口隔离开来.
如果你想隐藏accept方法,你总是可以有第二个接口,它是你的公共API,而t