mercredi 16 décembre 2015

Get specialized class from Abstract Factory

I have three classes, AbstractContext, ContextA and ContextB that i want to generalize in terms of creation but i want to access the specific methods of each one on different contexts.

AbstractContext:

public abstract class AbstractContext {

    public abstract  void  print();
}

ContextA:

 public class ContextA extends AbstractContext {

        @Override
        public void print() {
            System.out.println("In context A");
        }

        public void doSomeA(){
            System.out.println("Do some A");
        }
    }

ContextB:

 public class ContextB extends AbstractContext {

        @Override
        public void print() {

        }

        public void doSomeB(){
            int a=1;
            System.out.println(a);
        }

    }

I implemented the abstract factory pattern so i could generalize creation of these classes:

AbstractFactory :

public abstract class AbstractFactory {

    public abstract AbstractContext createContext();

}

FactoryA:

public class FactoryA extends AbstractFactory {

    @Override
    public AbstractContext createContext() {
        AbstractContext newClass = new ContextA();
        return newClass;
    }

}

FactoryB

public class FactoryB extends AbstractFactory {

    @Override
    public AbstractContext createContext() {
        AbstractContext newClass = new ContextB();
        return newClass;
    }

}

FactoryMaker

public class FactoryMaker {
    private static AbstractFactory factory = null;

    public static AbstractFactory getFactory(String condition) {
        if (condition == "A") {
            factory = new FactoryA();
        } else {
            factory = new FactoryB();
        }

        return factory;
    }
}

The problem here is, after an instance is created, since all factories return the base type i can't access any of the concrete methods of each subclass.

public class Main {

    public static void main(String[] args) {

        AbstractContext contextA = FactoryMaker.getFactory("A").createContext();
        contextA.print();    //Works fine
        contextA.doSomeA(); //Won't compile

        AbstractContext contextB = FactoryMaker.getFactory("").createContext();
        contextB.print(); //Works fine
        contextB.doSomeB(); //Won't Compile

    }
}

On a first attempt, i tried to create methods with the same signature accepting different subtypes of the class, but then i got compile errors since the base type doesn't match the concrete types the methods expect:

public static void process(ContextA context){
        context.doSomeA();
}

public static void process(ContextB context){
        context.doSomeB();
}

Is there anyway to achieve what i'm trying to do ?

To give you an additional context, i'm creating a Java shared library (API) that will be used by other developers, what i'm trying to do is find a way that developers don't have to think what kind of context they are creating. I want them to request a context and work from that point fill the properties that each context has then the api will process the specific parts of each context.

Aucun commentaire:

Enregistrer un commentaire