Java 一种层次化的选项分配继承方法

Java 一种层次化的选项分配继承方法,java,inheritance,options,Java,Inheritance,Options,我正在设计一个期权分配框架 我构建了一个选项类: public class MyOptionModule { public MyOptionModule() { } public void addOption(String option, String explanation) { //... } public void printHelp() { //... } public void parse(St

我正在设计一个期权分配框架

我构建了一个选项类:

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
 */
现在我的问题是,我的程序有一些未知的模块,我想调用其中的一些

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
}

Class除了反射或使用本机代码之外,我想不出任何方法在保持您的方法
静态的情况下实现此功能
(在Java8中,确实可以在接口中声明
静态
方法,但不能在实现类中重写它们。)

但是,由于您询问是否有任何设计来避免这种情况,因此有:。
长话短说,我想你对他们很熟悉:
您可以将
类及其所有静态成员转换为factory类的实例,然后在其上使用接口。
建立一个像

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

    private ExampleFactory(){}

    public Example newExample(){ /* ... */ }
}
可能是最接近你所要求的。

您有一个额外的类,必须实例化示例,如
ExampleFactory.INSTANCE.newExample()
,而不是
newExample()
,但仅此而已。

否。您必须使用反射或接口和实例

如果工具实例与选项无关,为什么不将两者分开

OptionModule.java:

public interface OptionModule {

    void assignOptions(MyOptionsModule optionsModule);
}
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()
        );
    }
}
public static class CustomToolModule {

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

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

public class MyOptionsModuleFactory {

    public static void createOptionsModule(Consumer<MyOptionsModule>... modules) {
        MyOptionsModule optionsModule = ...
        for(Consumer<MyOptionsModule> module : modules) {
            module.accept(optionsModule);
        }
    }
}
如果您使用的是Java 8,则可以使用方法引用来完成类似于所需的操作:

CustomToolModule.java:

public interface OptionModule {

    void assignOptions(MyOptionsModule optionsModule);
}
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()
        );
    }
}
public static class CustomToolModule {

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

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

使用java 8,您可以在接口中使用静态方法;)你能用抽象类来声明静态方法而不是接口吗?谢谢你的想法,但我认为这是不可能的。因为在我的设计中,我需要让类重写静态方法,因为每个类都有不同的选项要分配。@VeselinDavidov:Java 8中接口中的静态方法既不可重写,也不是契约的一部分。Java8只允许您在接口中实现静态方法。