首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将属性传递给工厂方法

将属性传递给工厂方法
EN

Stack Overflow用户
提问于 2016-01-12 00:26:35
回答 4查看 2.1K关注 0票数 4

我有一个工厂方法,它返回接口的实现。问题是-实现有不同的构造函数参数。

我的问题是-如何通过工厂方法将参数传递给接口的不同实现?

我有一个想法,但我不确定它是否有意义--将Properties对象传递给工厂方法?通过这种方式,每个接口实现都可以获得其构造函数所需的属性,而工厂接口将是统一的。

这是有意义的,还是有更好的解决方案?

我决定加一个例子,这样我就可以更好地澄清这个问题。

假设我们有接口SomeAlgorithm,我们有具体的算法,其中每个算法可能有不同的参数,例如

代码语言:javascript
运行
复制
SomeAlgorithm algo = new Algo1();
SomeAlgorithm algo = new Algo2(noOfIterations);
SomeAlgorithm algo = new Algo3(precision, boundary);

我希望能够做一些事情,比如

代码语言:javascript
运行
复制
SomeAlgorithm algo = AlgoFactory.getAlgo("algoName");

我处理不同参数的方法是

代码语言:javascript
运行
复制
SomeAlgorithm algo = AlgoFactory.getAlgo("algoName", properties); 

然后,如果算法有参数(例如Algo1没有参数),AlgoFactory可以将适当的属性传递给具体的算法构造函数。如果某些属性不存在,则可以传递默认值(如果算法中需要该值)。

如你所见,我希望能够动态改变算法。用户在运行时选择算法,并传递适当的参数,这些参数将放入属性对象中。

这有意义吗?

EN

回答 4

Stack Overflow用户

发布于 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标准库中,都远远不是完美的,但是你真的应该实现一些简单的东西,而不是在这样的问题上浪费太多的时间。

票数 1
EN

Stack Overflow用户

发布于 2016-01-12 00:45:30

一种可能的方法是使用Abstract Factory模式,这比传递Properties来确定结果类型更安全:

代码语言:javascript
运行
复制
// 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();
    }
}
票数 0
EN

Stack Overflow用户

发布于 2016-01-12 17:30:02

我认为策略模式更适合这里。你不需要把参数传递给构造器。它们看起来像是用于计算的参数。

如果您的算法使用相同的工作,例如计算税收,可以这样做。但如果他们做了不同的事情-考虑使用其他方法或提供更多细节,看看可以做些什么。

因此,对于税收计算,它可以是:

代码语言:javascript
运行
复制
taxCalculator = taxCalculatorFactory.Get(currentCountry);
taxAmount = taxCalculator.Calculate(countrySpecificTaxProperties);

只需为您countrySpecificTaxProperties使用一些接口,例如ITaxParams

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34726422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档