我有一个工厂方法,它返回接口的实现。问题是-实现有不同的构造函数参数。
我的问题是-如何通过工厂方法将参数传递给接口的不同实现?
我有一个想法,但我不确定它是否有意义--将Properties对象传递给工厂方法?通过这种方式,每个接口实现都可以获得其构造函数所需的属性,而工厂接口将是统一的。
这是有意义的,还是有更好的解决方案?
我决定加一个例子,这样我就可以更好地澄清这个问题。
假设我们有接口SomeAlgorithm,我们有具体的算法,其中每个算法可能有不同的参数,例如
SomeAlgorithm algo = new Algo1();
SomeAlgorithm algo = new Algo2(noOfIterations);
SomeAlgorithm algo = new Algo3(precision, boundary);我希望能够做一些事情,比如
SomeAlgorithm algo = AlgoFactory.getAlgo("algoName");我处理不同参数的方法是
SomeAlgorithm algo = AlgoFactory.getAlgo("algoName", properties); 然后,如果算法有参数(例如Algo1没有参数),AlgoFactory可以将适当的属性传递给具体的算法构造函数。如果某些属性不存在,则可以传递默认值(如果算法中需要该值)。
如你所见,我希望能够动态改变算法。用户在运行时选择算法,并传递适当的参数,这些参数将放入属性对象中。
这有意义吗?
发布于 2016-01-12 00:37:44
已编辑问题的更新(rev43552065-8ee8-47e8-bc96-c660c3836998):
您的示例不是典型的工厂模式。如果您有三种算法需要通过名称引用,并为特定算法提供特定参数,那么为什么要使用工厂?您可能应该阅读著名的"Effective Java“一书中的"Item 1:考虑使用静态工厂方法而不是构造函数”。它描述了工厂方法的优点,我在您的示例中看不到这些优点。
这个问题有很多解决方案,您可以在各种流行的项目中找到数百个示例。
例如,DriverManager类使用一个类似URL的字符串(它包含变量格式的连接详细信息)和一个具有高级选项的附加Properties对象(example)。
工厂方法通常应该足够抽象,以便在不为特定实现指定任何额外参数的情况下获得工作实现。它应该“隐藏”实现细节。
如果需要传递额外的/可选的属性,那么传递一个Properties对象是很常见的。
有不同的策略。例如,UrlConnection是一个抽象类。可以通过调用URL.openConnection()来检索实例,但是,许多选项只能通过将返回的UrlConnection转换为特定的子类型来设置,例如HttpUrlConnection。
我相信没有一个单一的解决方案可以适用于所有的情况,我非常确定许多解决方案,甚至可能在Java标准库中,都远远不是完美的,但是你真的应该实现一些简单的东西,而不是在这样的问题上浪费太多的时间。
发布于 2016-01-12 00:45:30
一种可能的方法是使用Abstract Factory模式,这比传递Properties来确定结果类型更安全:
// we will be creating subtypes of Vehicle
interface Vehicle {
    void move();
}
class Car implements Vehicle {
    Car(String vehicleId, int seatsNumber) {}
}
class Motorcycle implements Vehicle {
    Motorcycle(String vehicleId) {}
}
// ... via subtypes of VehicleFactory
interface VehicleFactory<T extends Vehicle> {
    T create(String vehicleId);
}
class FourSeatedCarFactory implements VehicleFactory<Car> {
    @Override
    public Car create(String vehicleId) {
        return new Car(vehicleId, 4);
    }
}
class MotorcycleFactory implements VehicleFactory<Motorcycle> {
    @Override
    public Motorcycle create(String vehicleId) {
        return new Motorcycle(vehicleId);
    }
}
class FactoryClient {
    void useVehicle(VehicleFactory<?> factory) {
        factory.create("COOL_PLATE_NAME").move();
    }
}发布于 2016-01-12 17:30:02
我认为策略模式更适合这里。你不需要把参数传递给构造器。它们看起来像是用于计算的参数。
如果您的算法使用相同的工作,例如计算税收,可以这样做。但如果他们做了不同的事情-考虑使用其他方法或提供更多细节,看看可以做些什么。
因此,对于税收计算,它可以是:
taxCalculator = taxCalculatorFactory.Get(currentCountry);
taxAmount = taxCalculator.Calculate(countrySpecificTaxProperties);只需为您countrySpecificTaxProperties使用一些接口,例如ITaxParams
https://stackoverflow.com/questions/34726422
复制相似问题