简体   繁体   中英

passing concrete factory into abstract factory class - java

I'm creating a abstractFactory class and I want to be able to send the concrete factory as a parameter. This way I can remove the if/else chain inside my abstract class.

My problem is I'm not sure how to typecast it back to the concrete class within my abstract class in order to call the createVehicle() method.

car = UniversalVehicleFactory.getFactory().createVehicle(CarFactory);
plane = UniversalVehicleFactory.getFactory().createVehicle(PlaneFactory);

Inside UniversalVehicleFactory I have the method createVehicle which is the method I'm having a problem with. What I'm trying to achieve is: take the parameter, determine its class and cast it to that, then call its internal createVehicle class.

public Vehicle createVehicle(AbstractFactory factory) {

    // I want to take factory,
            // cast it to the concrete factory, and
            // call createMethod() on the factory 

    return factory.getInstance().createVehicle();       
}

Help with this problem much appreciated!

I'll answer your question, but I'm curious why you want a universal factory to call a method of an abstract factory, if indeed you have to supply an instance of that factory as a parameter; you would be better off just invoking the creation method of the abstract factory directly.

Generics were invented for this purpose.

interface Factory< T > {
    T make();
}

public class CarFactory implements Factory< Car > {
    Car make() { ... }
}

public class PlaneFactory implements Factory< Plane > {
    Plane make() { ... }
}

public class UniversalVehicleFactory {
    public < T extends Vehicle > T make( Factory< T > factory ) {
        return factory.make();
    }
}

You'll notice that UniversalVehicleFactory doesn't implement Factory< T >.

I think you are trying to apply Abstract Factory pattern here. Here are my solution:

You can have interface VehicleFactory and factory classes:

interface VehicleFactory {
    Vehicle createVehicle();
}

class CarFactory implements VehicleFactory {
    public Vehicle createVehicle() {
        return new Car();
    }
}

class PlaneFactory implements VehicleFactory {
    public Vehicle createVehicle() {
        return new Plane();
    }
}

Then if you want to centralize all the factory, you can have a UniversalVehicleFactory :

class UniversalVehicleFactory {

    private Map<Class<T extends VehicleFactory>, VehicleFactory> factories;

    static {
        factories = new HashMap<Class<T extends VehicleFactory>, VehicleFactory>();
        factories.put(CarFactory.class, new CarFactory());
        factories.put(PlaneFactory.class, new PlaneFactory());
    }

    public static VehicleFactory getFactory(Class<T extends VehicleFactory> factoryClass) {
        return factories.get(factoryClass);
    }

}

Then in your code, use can use it like this:

Vehicle car = UniversalVehicleFactory.getFactory(CarFactory.class).createVehicle();
Vehicle plane = UniversalVehicleFactory.getFactory(PlaneFactory.class).createVehicle();

Here is some generalized code that might help you out:

public class A 
{
    public void paint(Graphics g)
    {

    }
}

public class B extends A
{
    public static void main(String args[])
    {
        A a = new A();
        B b = new B();

        // This is the only one that won't work, because a is not an instance of b.
        if(a instanceof B)
            ((B)a).draw(new Graphics()); 

        if(b instanceof B)
            ((B)b).draw(new Graphcis());

        if(a instanceof A)
            ((A)a).paint(new Graphics());

        if(b instanceof A)
            ((A)b).paint(new Graphics());
    }

    public void draw(Graphics g)
    {

    }
}

instanceof is a great tool to use before typecasting to avoid errors. I hope this helped, if it was too general and you want me to apply it more to your situation let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM