2015-04-30 41 views
0

我正在設計一個選項分配框架。分層選項分配繼承

我構建的期權類別:

public class MyOptionModule { 

    public MyOptionModule() { 
    } 

    public void addOption(String option, String explanation) { 
     //... 
    } 
    public void printHelp() { 
     //... 
    } 
    public void parse(String[] args) { 
     //... 
    } 
} 

對於每一個需要用戶輸入選項模塊,它將有一個靜態方法:

public static void assignOptions(MyOptionModule optionModule) { 
    optionModule.addOption("o", "Some options"); 
} 

在更復雜的情況下,一些模塊可能包括其他模塊工作。這裏有一個例子:

class ReaderClass { 
    public static void assignOptions(MyOptionModule optionModule) { 
     optionModule.addOption("i", "Input file for reader"); 
    } 
} 

class WriterClass { 
    public static void assignOptions(MyOptionModule optionModule) { 
     optionModule.addOption("o", "Output file for reader"); 
    } 
} 

public class OutClass { 
    public static void assignOptions(MyOptionModule optionModule) { 
     optionModule.addOption("x", "Some other options in Out Class"); 
     optionModule.addOption("y", "Some other options in Out Class"); 
     optionModule.addOption("z", "Some other options in Out Class"); 
    } 

    public static void main(String[] args) { 
     MyOptionModule optionModule = new MyOptionModule(); 
     ReaderClass.assignOptions(optionModule); 
     WriterClass.assignOptions(optionModule); 
     OutClass.assignOptions(optionModule); 

     if (args.length == 0) { 
      optionModule.printHelp(); 
     } 
     optionModule.parse(args); 
    } 
} 

的例子幫助菜單:

/* 
======== The help menu ======== 
i: Input file for reader 
o: Output file for reader 
x: Some other options in Out Class 
y: Some other options in Out Class 
z: Some other options in Out Class 
*/ 

現在我的問題是,我的計劃是給一些不知名的模塊,我想打電話給他們的assignOptions。

Class<? extends XXXX> toolClass = null; // Some class with assignOptions 
try { 
    toolClass.getMethod("assignOptions", MyOptionModule.class).invoke(null, optionModule); 
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { 
    // Exceptions, no options if NoSuchMethodException 
} 

儘管可以使用反射,但是如果我可以檢查某個類是否實現assignOptions方法,那將會很好。 assignOptions應該是靜態的,因爲類實例與要分配的選項無關。但是,我們不能將靜態方法的接口用於這種指示(它已經進行了很多討論)。那麼有沒有什麼設計可以避免反射,而我們無法在界面中獲得靜態方法?謝謝!

+0

使用java 8,你可以在接口的靜態方法;) –

+0

你可以使用抽象類的靜態方法宣告存在的,而不是接口? –

+0

感謝您的想法,但我不認爲這是可能的。因爲在我的設計,我需要讓類中重寫靜態方法,爲每個類都有不同的選項來進行分配。 –

回答

2

不需要您必須使用反射或接口和實例。

如果工具實例與選項無關,爲什麼不把它們分開?

OptionModule.java:

public interface OptionModule { 

    void assignOptions(MyOptionsModule optionsModule); 
} 

MyOptionsModuleFactory.java:

public class MyOptionsModuleFactory { 

    public static void createOptionsModule(Consumer<MyOptionsModule>... modules) { 
     MyOptionsModule optionsModule = ... 
     for(Consumer<MyOptionsModule> module : modules) { 
      module.accept(optionsModule); 
     } 
    } 
} 

CustomToolModule。Java的:

public class CustomToolModule { 
    public static class Options implements OptionsModule { 
     void assignOptions(MyOptionModule optionModule) { 
      ... 
     } 
    } 


    public static void main(String[] args) { 
     MyOptionsModule optionsModule = MyOptionsModuleFactory.createOptionsModule(
       new CustomToolModule.Options() 
     ); 
    } 
} 

如果您使用的是Java 8中,您可以使用方法引用來完成類似的東西,你想要什麼:

CustomToolModule.java:

public static class CustomToolModule { 

    public static void assignOptions(MyOptionsModule optionsModule) { 
     ... 
    } 

    public static void main(String[] args) { 
     MyOptionsModule optionsModule = MyOptionsModuleFactory.createOptionsModule(
       CustomToolModule::assignOptions, 
       CustomToolModule2::assignOptions 
     ); 
     ... 
    } 
} 
0

除了反思或使用本機代碼,我想不出任何方式使這項工作,同時保持您的方法static
(在Java 8,你確實可以宣佈接口static方法,但你不能在實現類覆蓋它們。)

不過,既然你問我有沒有任何設計,以避免這種情況,是有是:Factories
我假設你熟悉他們,所以長話短說:
您可以將您Class及其所有靜態成員轉變爲一個工廠類,可以在其上再使用的接口的實例
建立一個工廠類像

public class ExampleFactory 
{ 
    public static final ExampleFactory INSTANCE = new ExampleFactory(); 

    private ExampleFactory(){} 

    public Example newExample(){ /* ... */ } 
} 

可能是你可以得到你的要求最接近的。
你有一個額外的類,你必須instanciate例如ExampleFactory.INSTANCE.newExample()而不是new Example(),但就是這樣。