我想让我的项目可以通过插件扩展。对于该接口的用户,我想创建一个单独的小jar(plugin.jar)文件,公开编写插件所需的一切。
该插件应该只实现一个方法double Calculate (double)
。为此,我可以公开一个接口。但我也希望插件能够调用某个函数double getParameter(string)
现在它变得棘手(至少对我而言)。 getParameter
的实际实现取决于其他一些我不想在plugin.jar中引用的jar。 (出于清洁原因,仅此而已)所以我不能为我的用户提供某种类型的PluginBase类。
我提出的最佳解决方案是使用pImpl Idiom和其他接口的某种组合:
我通过在一个只包含final getParameter
的接口的Object上调用它来公开一个实现getParameter
的抽象基类。在我的应用程序中创建插件时,会传递此对象作为getParameter
函数的实现。但是,这意味着此PluginBase类需要setImplementation
函数。
用户方:
class UserPlugin extends PluginBase
{
@Override
public double Calculate(double input)
{
return input + this.getDoubleInput("X") + this.getDoubleInput("Y");
}
}
Jar提供插件接口和类
public interface IHasInputParameters { Double getParameter(String s) }
public class PluginBase implements IHasInputParameters
{
private IHasInputParameters impl;
public abstract double Calculate(double input)
@Override
public final Double getParameter(String s) { return impl.getParameter(s));}
public final void SetImplementation(IHasInputParameters i) { this.impl = i;}
}
内部
class PluginImpl implements IHasInputParameters
{
@Override
public final Double getParameter(String s)
{ //// do stuff that depends on stuff I don't want to expose}
}
这基本上有效。但不得不面对问题。
插件的初始化很尴尬。该插件需要其实现来调用getParameter,但实现需要插件来调用Calculate。
PluginImpl implementation = new PluginImpl ();
Plugin plugin = new Plugin();
plugin.setImplementation(implementation);
implementation.SetImplementation(plugin);
有更容易/更安全的方法吗?