Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何创建一个组合,该组合使用来自提供者的组件,而提供者本身应该添加到该组合中?_Java_Design Patterns_Serviceloader - Fatal编程技术网

Java 如何创建一个组合,该组合使用来自提供者的组件,而提供者本身应该添加到该组合中?

Java 如何创建一个组合,该组合使用来自提供者的组件,而提供者本身应该添加到该组合中?,java,design-patterns,serviceloader,Java,Design Patterns,Serviceloader,标题可能有点复杂,但我没有看到任何其他方式来表达我的问题 我正在从事一个项目,其中某些组件通过加载几个文件并将其转换为Java组件来初始化,其他组件则由ServiceLoader加载,因为它们已经作为Java类存在。然后,所有这些对象都由提供者映射,以便从那里检索它们 public class Provider { private Map<String, Component> map; public Provider() { /*

标题可能有点复杂,但我没有看到任何其他方式来表达我的问题

我正在从事一个项目,其中某些组件通过加载几个文件并将其转换为Java组件来初始化,其他组件则由ServiceLoader加载,因为它们已经作为Java类存在。然后,所有这些对象都由提供者映射,以便从那里检索它们

public class Provider {

    private Map<String, Component> map;

    public Provider() {
        /*
         * Load files, transform, and add them to the map 
         * with keys being their names
         */
        /*
         * Load Java components and add them to the map 
         * with keys being their names
         */
    }

    public Component getComponent(String name) {
        return this.map.get(name);
    }
}

public interface Component {
    public Number execute();
}
只需将该组合添加到特定的META-INF文件,即可将其添加到提供程序中。然后它将由ServiceLoader处理

对我来说,这是一种循环依赖。我必须在META-INF文件中定义ServiceLoader应该收集哪些Java类。这也将包括新实现的组合。但是,只要提供者加载了所有其他度量,就无法创建该度量

public class Composite implements Component {
    private Component component1, component2;

    public Composite() {
        Provider provider = new Provider();
        this.component1 = provider.getComponent("Comp1");
        this.component2 = provider.getComponent("Comp2");
    }

    public Number execute() {
        return this.component1.execute() + this.component2.execute();
    }
}

有什么模式或不同的方法可以用来解决这个问题吗?

更有可能的是,你应该有一个连锁店。因此,在您的
组合中,您应该创建一个名为
CompositeComponent
的接口,而不是创建
Provider
的新实例,该接口将扩展
Component
,并具有另一个方法
init(Provider-Provider)
。或者最好在代码中显示:

public interface CompositeComponent extends Component {

    void init(Provider provider);

}
然后在您的
提供者中

public Component getComponent(String name) {
    Component component = this.map.get(name);
    if (component instanceof CompositeComponent) {
        ((CompositeComponent)component).init(this);
    }
}

我看这确实行得通。但在返回提供程序之前检查类型不是很糟糕吗?我不想让提供者知道组件的任何子类,因为它只用于提供组件。对我来说,它们实际上应该是无类型检查,然后包括方法
voidinit(Provider)
组件