【发布时间】:2016-06-29 18:59:40
【问题描述】:
我有以下课程(在 JEE 中,可以在 Spring 中类似地制作):
@Singleton
public class MyUnknownPatternClass {
@Inject @Any Instance<SomeInterface> instances;
public SomeInterface getMatchingInstance(Object someDiscriminator) {
for(SomeInterface instance : instances) {
if(instance.supports(someDiscriminator)) {
return instance;
}
}
throw new IllegalArgumentException("Could not find a matching instace for " + someDiscriminator.toString());
}
}
使用依赖注入的发现来定位匹配接口的所有实例,这让我可以完全解耦策略和使用它的代码。
例如,对于一个旅行推销员应用程序,我有不同的 TransportProviders 来实现 travel(Location l) 方法,然后我的业务逻辑可以专注于以下常规流程:
Salesman m =...;
Location l = m.getStartLocation();
TransportProvider t = myUnknownPatternClass.getMatchingInstance(m.getTravelMethod());
for(Location d : m.getDestinationsToVisit())
l = t.travel(d);
m.doBusinessHere(l);
}
从而将销售人员的出行方式与步行、乘船、汽车或其他任何方式脱钩。
我的理解是工厂实际上实例化了对象。服务定位器更通用,并允许运行时注册,而上面的代码似乎两者都没有。它不是白板模式,因为它只返回一个实例。
但是,这是一个非常有用的模式,如果能恰当地谈论它会很好。
那么,它是什么?
那么该类的正确名称是什么
(即SomeInterfaceLocator,或SomeInterfaceFactory)?
编辑:
我找到了这个https://en.wikipedia.org/wiki/Command_pattern#Java_8
是命令工厂模式吗?
【问题讨论】:
-
在我看来就像一个工厂——在给定一组参数的情况下提供预期类型的对象。它返回的实例是通过 DI 实例化的这一事实并不会改变它的功能,只会改变它的底层实现。
-
工厂的“描述”不是暗示返回值是你的(即不共享)吗?因为通常工厂返回可以修改、调整、删除等的唯一对象。这并没有降低(尽管这很困难,因为接口可能不允许这样做)。如果您向其他人描述这一点,您会称其为工厂但不同,如果是,那是什么?
-
它返回一个实例——消费者无法知道该实例是共享的——它可以通过允许此类行为的任何属性或方法进行修改。注入构造函数的实例可能是新实例,这个对象无法知道或强制执行这一点——它只知道它有一个对象列表。随便你怎么称呼它,但从外面看,它的外观、气味和行为就像一个工厂。
标签: design-patterns dependency-injection factory service-locator