[英]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.