0

As you all know that the AbstractFactory helps creating object without knowledge of creation process. But the complexity of the pattern will increase by the time, when new factory is added or large modifications are made within the factory class. This will require a heavy change on abstract factory creator class.

I used to use AbstractFactory, but with my own modification & it's like: Replace abstract factory creator class with empty interface, which will be implemented by factory classes. Then cast returned object from FactoryCreator class to the real factory I want. This worked, but I wonder if this breaks the pattern or is it a bad practice on the pattern or does it have any drawback that would lead to the same complexity in the future development?

Below is a very simple implementation of the pattern that I took from the book & my modifications as well:

Shape factory:

public interface Shape {
    void draw();
}
public class Circle implements Shape {
    @Override
    public void draw() {
        // Draw circle
    }
}
public class Rectangle implements Shape {
    @Override
    public void draw() {
        // Draw rectangle
    }
}
public class ShapeFactory implements IFactory {
    public Shape getShape(String shape) {
        if (shape.equalsIgnoreCase("CIRLE")) {
            return new Circle();
        } else if (shape.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }

        return null;
    }
}
//public class ShapeFactory extends AbstractFactory {
//    @Override
//    public Color getColor(...) {
//        //
//    }
//    @Override Shape getShape(...) {
//        //
//    }
//}

Color factory:

public interface Color {
    void fill();
}
public class Red implements Color {
    @Override
    public void fill() {
        // Fill red
    }
}
public class Green implements Color {
    @Override
    public void fill() {
        // Fill green
    }
}
public class ColorFactory implements IFactory {
    public Color getColor(String color) {
        if (color.equalsIgnoreCase("RED")) {
            return new Red();
        } else if (color.equalsIgnoreCase("GREEN")) {
            return new Green();
        }
    }
}
//public class ColorFactory extends AbstractFactory {
//    @Override
//    public Color getColor(...) {
//        //
//    }
//    @Override Shape getShape(...) {
//        //
//    }
//}

Factory creator interface:

public interface IFactory { }
//public abstract class AbstractFactory {
//   abstract Color getColor(String color);
//   abstract Shape getShape(String shape) ;
//}

Factory creator:

public class FactoryCreator {
    public static IFactory getFactory(String factoryName) {
        if (factoryName.equalsIgnoreCase("SHAPE")) {
            return new ShapeFactory();
        } else if (factoryName.equalsIgnoreCase("COLOR")) {
            return new ColorFactory();
        }

        return null;
    }
}

Usage:

public class demo {
    ShapeFactory shapeFactory = (ShapeFactory)FactoryCreator.getFactory("SHAPE");
    ColorFactory colorFactory = (ColorFactory)FactoryCreator.getFactory("COLOR");

    shapeFactory.getShape("CIRCLE").draw();
    shapeFactory.getShape("RECTANGLE").draw();
    colorFactory.getColor("RED").fill();
    colorFactory.getColor("GREEN").fill();
}
RyanB
  • 1,287
  • 1
  • 9
  • 28
  • 1
    Could you please cite the book from which this example is taken? – Fuhrmanator Dec 10 '15 at 17:08
  • @Fuhrmanator I took it from an online book here: http://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm – RyanB Dec 11 '15 at 03:13
  • The design is questionable in that online tutorial. It makes little sense that subclasses of the abstract factory only do either shapes or colors, especially when they have to inherit the methods for both. This is not abstract factory according to the GoF. – Fuhrmanator Dec 12 '15 at 14:07

3 Answers3

0

Design patterns are not a guarantee to to the right thing... you have to use your head first...

history showed that many people had a certain problem with [xxx] and a lot of people could solve the problem with Design-Pattern [yyy]. That's how desgin pattern evoveld and how they are defined.

enter image description here

You cannot say i'll implement this (or that) pattern and i'll have no problems anyway. you have to think, describe your problem and see if this pattern would help you to design your architecture.

Obviously: your programm implementation is so simple that abstractFactory is overhead, and you already solved that with using mere interfaces.

ok, let's speak the obvoius: AbstractFactory is not the solution to your problem:

first: define your problem: i want to create parametrized objects in a simple way. a) parametrized with shape and color and b) simple way

possible solution: factory-methode (think: you have the interface Shape with two implementations and the interface Color with two implementations)

public ShapeFactory{
    public static Shape create(String shape){
         if ("CICRCLE".equals(shape)) //your code from above
    }
}

and a Color factory

public ColorFactory{
    public static Color createColor(String color){
        if("GREEN".equals(color) ) // your code from above
    }
}

using these design pattern you can solve your problem as defined above... (you can make one factory wich provides factory-methods for both interfaces, if you want to make it even shorter)

Martin Frank
  • 3,445
  • 1
  • 27
  • 47
  • Obviously, using interface could produce the same result in compare with abstract factory class. Could you point me out why abstract class was used instead of interface, even though the use of interface will bring down the complexity when implement the pattern? – RyanB Dec 10 '15 at 07:04
0

So the question in essence boils down to difference between abstract class and interface.

There are many sources on this discusion:

see here

What you need to understand about the patterns is that they are designed to be template for solution. It will happen rarely that you can copy paste pattern with zero modification and expect to fit your problem perfectly.

As for your question, can you implement AbstractFactory pattern with a FactoryCreator interface instead of abstract class ?

Surely you can, this is an implementation detail which does not break the intent of the pattern.

Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.

Edit

You are looking at one specific implementation of this pattern in which author decided to implement the template with abstract class.

Community
  • 1
  • 1
John
  • 5,189
  • 2
  • 38
  • 62
0

As per my understanding in the above problem, one wants to create a shape and then fill color in it. If thats the case one can make it bit better by adding Builder pattern on top of factory.

class ShapeBuider
{
    private String color;

    private String shape;

    /**
     * @param color the color to set
     */
    public void setColor(String color) {
        this.color = color;
    }

    /**
     * @param shape the shape to set
     */
    public void setShape(String shape) {
        this.shape = shape;
    }

    public void build()
    {
        // create shape
        // create color
        // fill shape with color
    }

    public Object get()
    {
        // return the created object in build method here.
        return null;
    }
}

This builder approach will make sure that the right color is applied to right shape.

Harbeer Kadian
  • 364
  • 2
  • 14