dimanche 27 janvier 2019

Abstract factory design pattern and generics - Java

It's the first time I'm using this design pattern and I'm having some difficulties. Taking this image as reference:

enter image description here

I have two AbstractProduct that I would like to create a factory for, since they come in different "families". One of the products is a collection of the other.

public abstract class Frame{
    ...
}

public abstract class FrameMap<F extends Frame>{
    protected TreeMap<Integer, F> map;
    ...
}

Taking one family as an example (the one for App1) these are the concrete Product:

public class App1Frame extends Frame{
    ...
}

public class App1FrameMap extends FrameMap<App1Frame>{
    ...
}

Then I have created the AbstractFactory:

public abstract class ApplicationFactory{
    //Frame factory methods
    public abstract Frame makeFrame();

    //FrameMap factory methods
    public abstract FrameMap<? extends Frame> makeFrameMap();
}

And the ConcreteFactory for App1:

public class App1Factory extends ApplicationFactory{
    //Frame factory methods
    public Frame makeFrame(){
        return new App1Frame();
    }

    //FrameMap factory methods
    public FrameMap<App1Frame> makeFrameMap(){
        return new App1FrameMap();
    }
}

All of this compiles, but I'm not liking it very much because my Client cannot do something like:

ApplicationFactory factory = new App1Factory();
FrameMap<Frame> frameMap = factory.makeFrameMap(); //This doesn't compile!

which is, at least conceptually, the goal of the pattern, i.e. letting the client only use the abstract classes. In order to make it work, I have to do something like this:

App1Factory factory = new App1Factory();
FrameMap<App1Frame> frameMap = factory.makeFrameMap(); //This compiles!

which seems going against the purpose of using the design pattern.

Do you know any better way of implementing this pattern in a situation like mine, i.e. using generics in the AbstractProduct, in order to let the Client only use the abstract classes without knowing the underlying implementation?

Aucun commentaire:

Enregistrer un commentaire