[英]Force a user of my library to implement an interface or extend an abstract class
我正在开发一个Android库(.aar),我想知道是否有可能如标题所示强制用户实现接口或扩展我库的抽象类。
我已经知道我可以在我的库中使用这样的类:
public class MyLibrary
{
public interface VariablesInterface
{
void createVariables();
}
private static VariablesInterface vi = null;
public void setVariablesInterface(VariablesInterface v)
{
vi = v;
}
private static void SomeWork()
{
if (vi == null)
{
throw new RuntimeException("You noob.");
}
else
{
// do work
}
}
}
该库将在某个时候“单独”工作,当涉及SomeWork()
,如果未实现该接口,它将崩溃,但这只能在运行时看到。
编译用户的应用程序时,有没有一种方法可以解决此问题?
目的是避免用户忘记自己必须实现而不必在文档中编写它,并希望用户可能会阅读它。
谢谢阅读 !
编辑
我认为这个问题需要一些增强和背景。 该库的目的是提供创建用于管理首选项的变量的类,例如:
public class VarPreferenceBoolean extends VarPreference
{
private boolean defaultValue;
public VarPreferenceBoolean(String key, boolean defaultValue)
{
super(key, true);
this.defaultValue = defaultValue;
}
public void setValue(Context context, boolean value)
{
SharedPreferences.Editor e = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE).edit();
e.putBoolean(key, value);
e.commit();
}
public boolean getValue(Context context)
{
readPropFile(context);
SharedPreferences sp = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE);
return sp.getBoolean(key, defaultValue);
}
}
int,string等也是如此。 在超类中,我将每个VarPreference添加到一个List中,以使库确认所有可用变量。 注意getter内部的readPropFile
。
然后,用户使用他的项目中的库,如下所示:
public class Constants
{
public static final VarPreferenceInt FILETYPE;
public static final VarPreferenceInt DATAMODE;
public static final VarPreferenceString URL_ONLINE;
public static final VarPreferenceBoolean UPDATING;
public static final VarPreferenceLong LAST_UPDATE;
static
{
FILETYPE = new VarPreferenceInt("FileType", MyFile.FileType.LOCAL.getValue());
DATAMODE = new VarPreferenceInt("DataMode", DataProvider.DataMode.OFFLINE.getValue());
URL_ONLINE = new VarPreferenceString("UrlOnline", "http://pouetpouet.fr");
UPDATING = new VarPreferenceBoolean("Updating", false);
LAST_UPDATE = new VarPreferenceLong("LastUpdate", 0L);
}
}
现在,当用户调用访问器时, readPropFile
将首先搜索.properties文件是否存在,并在发现VarPreference列表和文件属性之间匹配时,相应地修改首选项。 然后它将删除文件,访问器将返回该值。
今天就是这样。
现在,我们希望另一个应用程序(例如Pilot)能够获取用户应用程序(例如Client)的VarPreferences。 两者都实现该库。
飞行员发送一个Intent来请求Client的VarPreference列表,并额外添加Client的程序包名称。 库接收到该意图,请验证软件包名称,如果是客户端,则将其发回列表。
问题是,如果Client尚未启动,则不存在VarPreference,并且列表为空。
我需要强迫用户以我的库知道的方法创建他的VarPreference,以便能够在需要时调用它,并在必要时创建用户的VarPreferences。
希望这更清楚!
编辑
我和一位同事一起考虑了所有这一切,这让我们感到震惊的是,所有这一切都是偏颇的。
我没有很好地解释,即使我说了也没有足够考虑:一切都需要从库中完成。 因此,即使我为该库提供了接口,该应用程序也必须先运行并调用此操作才能使该库单独工作。
我们现在正要进行内省。 (这是目标,可能无法实现...)库中将有一个抽象类,其中包含一个抽象方法,用户可以在其中放置所有VarPreferences创建内容。 用户将必须扩展此类并调用该方法才能创建他的VarPreferences。 在该库中,一种方法将通过内省搜索抽象类的子级,创建该子级的实例,然后调用将创建VarPreferences的方法。
我将把抽象类和接口留在主库中,并通过类加载器从另一个库中加载其余代码。 JDBC的工作原理是这样的。
编译用户的应用程序时,有没有一种方法可以解决此问题?
我认为没有办法强制编译失败。 但是,如果强迫他们在构造函数中提供VariablesInterface
,则它将立即失败。 使VariablesInterface
为final
并仅在构造函数中对其进行初始化:
public class MyLibrary {
private final VariablesInterface vi;
public MyLibrary(VariablesInterface vi) {
if (vi == null) {
throw new IllegalArgumentException("vi can't be null");
}
this.vi = vi;
}
...
如果无法更改构造函数,则还可以向某种SomeWork
公共方法添加某种配置检查方法,以确保正确完成vi
接线,但这需要仔细编程以确保覆盖所有公共方法。
public void somePublicMethod() {
checkWiring();
...
}
private void checkWiring() {
if (vi == null) {
throw new IllegalStateException("vi needs to be specified");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.