分层选项分配继承

时间:2015-04-30 07:30:24

标签: java inheritance options

我正在设计一个选项分配框架。

我构建了一个选项类:

 string str = "Test123(45)";
        string[] delimiters ={@"("};;
        string[] split = str.Split(delimiters, StringSplitOptions.None);
        var b=split[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);
    }
}

现在我的问题是我的程序被给了一些未知的模块,我想调用它们的assignOptions。

 /*
 ======== 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方法,那将会很棒。 assignOptions应该是静态的,因为类实例与要分配的选项无关。但是,我们不能使用静态方法的接口来进行这样的指示(已经进行了很多讨论)。那么有什么设计可以避免反射,而我们无法在界面中获得静态方法?谢谢!

2 个答案:

答案 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
        );
        ...
    }
}

答案 1 :(得分:0)

除了反思或使用本机代码之外,在保留方法static时,我想不出任何方法可以使这项工作。
(在Java 8中,您确实可以在接口中声明static方法,但是您无法在实现类中覆盖它们。)

但是,既然你问是否有任何设计来避免这种情况,那么可以:Factories
我假设你熟悉它们,所以长话短说: 您可以将Class及其所有静态成员转换为工厂类的实例,然后可以使用该界面。
建立像

这样的工厂类
public class ExampleFactory
{
    public static final ExampleFactory INSTANCE = new ExampleFactory();

    private ExampleFactory(){}

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

可能是你能得到的最接近你的要求 你有一个额外的类,你必须实例化像ExampleFactory.INSTANCE.newExample()而不是new Example()的实例,但就是这样。