![](/img/trans.png)
[英]what is the difference between factory and abstract factory design pattern in java?
[英]Abstract factory design pattern and generics - Java
这是我第一次使用这种设计模式,并且遇到了一些困难。 以此图像为参考:
我有两个AbstractProduct我想为其创建工厂,因为它们来自不同的“家庭”。 其中一种产品是另一种产品的集合。
public abstract class Frame{
...
}
public abstract class FrameMap<F extends Frame>{
protected TreeMap<Integer, F> map;
public F readByKey(Integer key){
return this.map.get(key);
}
public void put(Integer key, F frame){
this.map.put(key,frame);
}
...
}
请注意, FrameMap
是F
的集合(为简单起见,我省略了大多数其他方法),因此它需要能够获取和放置元素。 以一个家庭为例(App1的一个)为具体产品 :
public class App1Frame extends Frame{
...
}
public class App1FrameMap extends FrameMap<App1Frame>{
...
}
然后我创建了AbstractFactory :
public abstract class ApplicationFactory{
//Frame factory methods
public abstract Frame makeFrame();
//FrameMap factory methods
public abstract FrameMap<? extends Frame> makeFrameMap();
}
而App1的ConcreteFactory :
public class App1Factory extends ApplicationFactory{
//Frame factory methods
public Frame makeFrame(){
return new App1Frame();
}
//FrameMap factory methods
public FrameMap<App1Frame> makeFrameMap(){
return new App1FrameMap();
}
}
所有这些都可以编译,但是我不太喜欢它,因为我的客户无法执行以下操作:
ApplicationFactory factory = new App1Factory();
FrameMap<Frame> frameMap = factory.makeFrameMap(); //This doesn't compile!
至少从概念上讲,这是模式的目标,即让客户端仅使用抽象类。 为了使其正常工作,我必须执行以下操作:
App1Factory factory = new App1Factory();
FrameMap<App1Frame> frameMap = factory.makeFrameMap(); //This compiles!
这似乎与使用设计模式的目的背道而驰。
您是否知道在我的情况下(例如在AbstractProduct中使用泛型)实现这种模式的更好方法,以便让Client只使用抽象类而不知道底层实现?
您可以将泛型添加到ApplicationFactory
。
public class MainJava {
interface Frame{}
interface FrameMap<T extends Frame>{}
static class App1Frame implements Frame{}
static class App2Frame implements Frame{}
static class App1FrameMap implements FrameMap<App1Frame>{}
static class App2FrameMap implements FrameMap<App2Frame>{}
interface ApplicationFactory<T extends Frame> {
T makeFrame();
FrameMap<T> makeFrameMap();
}
static class App1Factory implements ApplicationFactory<App1Frame> {
@Override public App1Frame makeFrame() {
return new App1Frame();
}
@Override public FrameMap<App1Frame> makeFrameMap() {
return new App1FrameMap();
}
}
public static void main(String... args) {
ApplicationFactory<? extends Frame> factory = new App1Factory();
Frame frame = factory.makeFrame();
FrameMap<? extends Frame> map = factory.makeFrameMap();
}
}
还要注意应将ApplicationFactory
对象注入客户端。 如果客户端直接调用new App1Factory()
,则没有指向抽象的意义。 客户端可能在创建App1Factory
之后也可以使用它。
除了@ jaco0646解决方案之外,还有一种简单的方法可以解决将新创建的框架添加到地图的问题,即使您在运行时不知道实际的子类型或“家庭”。 只要您可以在以下方法中将frame和frame-map类型参数都绑定为具有相同的值:
public static <T extend Frame> FrameMap<T> makeAndAdd(final AbstractFactory<T> factory) {
T frame = factory.makeFrame();
FrameMap<T> map = factory.makeFrameMap();
map.add(frame);
return map;
}
当不可能将两个动作都放在相同的方法中时(例如,在不同的服务器调用上异步发生)。 您仍然可以通过使用带有类型参数的另一个类来实现这种联系,这些类具有不同的操作方法……这有点复杂,需要针对实际问题进行量身定制,但是想法是相同的从某种意义上说,您是在运行时使用类型参数来绑定给不同对象的类型参数值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.