Which Design Pattern is this: Factory Method or Abstract Factory
Asked Answered
B

2

5

I was reading about creational design patterns and have managed to utterly confuse myself between Factory , Abstract Factory and Factory method.

I am posting a code snippet below. Would someone be kind enough to let me know which one is this and (if possible) what changes could be made to the code to make it fall under the other categories?

#include "iostream.h"

#define QUIT 2

class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    void draw() {
        cout << "circle : draw" << endl;
    }
};
class Square : public Shape {
public:
    void draw() {
        cout << "square : draw" << endl;
    }
};

class Factory {
public:
    virtual Shape* createInstance(int id) = 0;
};

class SimpleShapeFactory : public Factory {
public:
    Shape* createInstance( int id) {
        if(id == 0)
            return new Circle;
        else if(id == 1)
            return new Square;
        else 
            return new Circle; //as a default
    }
};

int main() {
    Factory* factory = new SimpleShapeFactory();
    int choice = 0;
    Shape* shape;

    do
    {
        cout<<"\n 0. Circle";
        cout<<"\n 1. Square";
        cout<<"\n 2. Quit";
        cout<<"\n Enter your choice : ";

        cin>>choice;

        if(choice == QUIT)
            break;

        shape = factory->createInstance(choice);
        shape->draw();
    } while (choice !=QUIT);
}
Bambino answered 26/5, 2014 at 6:32 Comment(0)
W
4

This is none of the GOF creational patterns. It is a variation of the Abstract factory pattern sometimes called Parameterized factory pattern. The parameterized factory creates different objects depending on the parameter passed to the create method (often an Id or type specifier).

A GOF factory method in your example would like this (just an example... non sense...)

struct AreaCalculator {
    virtual double calculateArea() = 0;
};

struct CircleCalculator {
    CircleCalculator(const Circle& circle);
    double calculateArea() override;
};

struct Shape {
    virtual void draw() = 0;

    // This is the factory method:
    virtual std::unique_ptr<AreaCalculator> createCalculator() = 0;
};

struct Circle : Shape {
    void draw() override {
        cout << "circle : draw" << endl;
    }

    std::unique_ptr<AreaCalculator> createCalculator() {
        return make_unique<AreaCalculator>(*this);
    }
};

A GOF Abstract factory would look like this

struct Circle {
    virtual void draw() = 0;
};

struct StdoutCircle : Circle {
    void draw() override {
        cout << "circle : draw" << endl;
    }
};

struct Win32Circle : Circle {
    void draw() override {
        // ....
    }
};


struct ShapeFactory {
    virtual std::unique_ptr<Circle> createCircle() = 0;
    virtual std::unique_ptr<Rect> createRect() = 0;
};

struct StdoutShapeFactory : ShapeFactory {
    std::unique_ptr<Circle> createCircle() override {
        return make_unique<StdoutCircle>();
    }

    std::unique_ptr<Rect> createRect() override {
        // ...
    }
};
Widow answered 26/5, 2014 at 6:45 Comment(3)
I am not sure about GOF, have'nt read it. I was just reading about Factory patterns through multiple websites.Bambino
@Bambino I added examples of the two GOF patterns.Widow
Many thanks for the example. I havehad a cursory glance through them; was not able to derive much. However, that's my shortcoming- nothing wrong in your answer/ Its just that I will need to put a little more time to go through to grasp the difference. That said, I am marking your answer as the correct answer.Bambino
S
3

There are two related patterns, Factory method pattern and Abstract factory pattern. Yours is close to the second one. There is No pattern named Abstract.

Here is difference between them.

Shanley answered 26/5, 2014 at 6:37 Comment(1)
@Rakilbul: I am going thropugh the links you've provided but am having a hard time understanding them as the confusion still persists. As you've suggested it is currently an implementation of Abstract factory, would it be possible for you to explain what code changes can I do to make it factory method?Bambino

© 2022 - 2024 — McMap. All rights reserved.