2

I am going through the difference between Abstract Factory Pattern vs Factory Method Pattern. I understood that Factory Method is used to create one product only but Abstract Factory is about creating families of related or dependent products. But how Factory method pattern uses inheritance while the abstract factory pattern uses composition is unclear for me.

I know that this is been asked couple of times, Could any one please explain with the below code how inheritance and composition is happening?

Factory Method code

class IRose
{
public:
virtual string Color(void)=0;
};

class RedRose: public IRose
{
public:
string Color(void)
{
    return "Red";
}
};

class YellowRose: public IRose
{
public:
string Color(void)
{
    return "Yellow";
}
};

class IFactory
{
public:
virtual IRose* Create(string type)=0; 
//The factory create method in 90% of cases will take a parameter which 
//determines what kind of the object the factory will return.   
};

class Factory: public IFactory
{
public:
IRose* Create(string type)
{
    if ("Red" == type)
        return new RedRose();

    if ("Yellow" == type)
        return new YellowRose();

    return NULL;
}
};

int main()
{
IRose* p = NULL;
IFactory* f = NULL;

f = new Factory();  //You have to create an INSTANCE of the factory

p = f->Create("Red");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
p = f->Create("Yellow");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
return 1;
}

Abstract factory code.

class IFridge
{
public:
virtual string Run(void) = 0;
};

class FridgeSamsung : public IFridge
{
public:
string Run(void)
{
    return "You are now running Samsung Fridge\n";
}
};

class FridgeWhirlpool : public IFridge
{
public:
string Run(void)
{
    return "You are now running Whirlpool Fridge\n";
}
};

class IWashingMachine
{
public:
virtual string Run(void) = 0;
};

class WashingMachineSamsung : public IWashingMachine
{
public:
string Run(void)
{
    return "You are now running Samsung Washing Machine\n";
}
};

class WashingMachineWhirlpool : public IWashingMachine
{
public:
string Run(void)
{
    return "You are now running Whirlpool Washing Machine\n";
}
};

class IFactory
{
public:
virtual IFridge* GetFridge(void) = 0;
virtual IWashingMachine* GetWashingMachine(void) = 0;
};

class FactorySamsung : public IFactory
{
IFridge* GetFridge(void)
{
    return new FridgeSamsung();
}

IWashingMachine* GetWashingMachine(void)
{
    return new WashingMachineSamsung();
}
};

class FactoryWhirlpool : public IFactory
{
IFridge* GetFridge(void)
{
    return new FridgeWhirlpool();
}

IWashingMachine* GetWashingMachine(void)
{
    return new WashingMachineWhirlpool();
}
};

int main()
{
IFridge* fridge;    //Client just knows about fridge and washingMachine.
IWashingMachine* washingMachine; //and factory. He will write operations which
IFactory* factory; //work on fridges and washingMachines.

factory = new FactorySamsung; 
//This is the only place where the client
//has to make a choice. 

//The rest of the code below will remain same, even 
//if the factory is changed. He can change the factory and the same range
//of products but from a different factory will be returned. No need to 
//change any code.

fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";

delete factory;
factory = new FactoryWhirlpool;

//See same client code.
fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";
delete factory;
return 1;
}
Deepak
  • 47
  • 5
  • 1
    The first code doesn't look like a typical Factory Method to me. The Factory class with `Create(string type)` seems overcomplicated and unnecessary. Where did you get the code? Also, where did you read that *"Factory method pattern uses inheritance while the abstract factory pattern uses composition"*? – guillaume31 Jul 18 '18 at 09:00
  • @guillaume31 "Factory method pattern uses inheritance while the abstract factory pattern uses composition" this topic have been discussed in stackoverflow itself [here](https://stackoverflow.com/questions/22643449/abstract-factory-vs-factory-method-composition-vs-inplement) – Deepak Jul 18 '18 at 09:26
  • @guillaume31 The code i took as a reference from [here](http://ikeptwalking.com/factory-method-pattern/) if you feel this is not the right method please direct to the correct one. – Deepak Jul 18 '18 at 09:28
  • I find it a bit contrived. For a clearer example, look at Mark Seemann's sample code in the SO question you just linked to. – guillaume31 Jul 18 '18 at 09:30
  • Okay, there's a big flaw in the article you took the code from, because despite what the title claims, it explains the Factory pattern - whose primary goal is to extract complex creation logic out of a constructor into a separate class - instead of the Factory *Method* pattern per se. – guillaume31 Jul 18 '18 at 09:34
  • In Mark Seemann's example, there's composition in the first bit of code (Abstract Factory) because of the `private readonly IMyFactory factory` field. There's no composition in the second code (Factory Method) because there's no need for a member field, it's all done through inheritance. It's as simple as that. – guillaume31 Jul 18 '18 at 09:44
  • @guillaume31 i have checked multiple sources for Factory Method pattern and i have found the same procedure used [others](http://www.bogotobogo.com/DesignPatterns/factorymethod.php) ,please share any link that shows the correct way for Factory Method pattern – Deepak Jul 18 '18 at 09:46
  • @guillaume31 if possible can you explain me with a C++ code? – Deepak Jul 18 '18 at 09:48
  • [Wikipedia](https://en.wikipedia.org/wiki/Factory_method_pattern)? ;) – guillaume31 Jul 18 '18 at 09:48
  • I'm talking about the Factory Method pattern from the Gang of Four [Patterns book](https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8) here. There might be another Factory Method pattern in C++ literature but that's not what a majority of developers will spontaneously relate to. – guillaume31 Jul 18 '18 at 09:51

1 Answers1

2

This is a revised reply after some thought.

Factory Method: Usually, createObject() is a method of the Creator object.

Abstract Factory: Usually the Factory Object is an attribute of the Creator object.

Assume now that createObject() and Factory Object belong to their respective Creator.

Factory Method: createObject() may change in sub-classes of the Creator. This happens by changing the implementation of creatObject() via inheritance.

Abstract Factory: Factory Object may also change in sub-classes of the Creator. This change however happens by replacing one Factory Object with a different Factory Object ie the Creator object is changed by composition.

In your demo creatObject() and Factory Object are external to the Creator(s) so obscuring the distinction between composition/inheritance!

Christopher Okhravi has great youTube videos on patterns.

Factory Method https://www.youtube.com/watch?v=EcFVTgRHJLM&index=4&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc

Abstract Factory https://www.youtube.com/watch?v=v-GiuMmsXj4&index=5&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc

As requested here is a version of Factory Method (in C++ this time!). If you need any assistance interpreting let me know.

class IRose
{
public:
    virtual const char * Color(void) = 0;
};

class RedRose : public IRose
{
public:
    const char * Color(void)
    {
        return "I am a Red rose";
    }
};

class YellowRose : public IRose
{
public:
    const char * Color(void)
    {
        return "I am a Yellow rose";
    }
};

class RoseGarden
{
protected: class IRose* rose;   // a pointer to the garden's rose

public:
    virtual void createRose() { }  // abstract Factory Method

public: void sayColor() {
        cout << rose->Color() << '\n';
    }
};

class RedRoseGarden : public RoseGarden
{
public:
    void createRose()
    {
        this->rose = new RedRose();   // concrete factory method
    }
};

class YellowRoseGarden : public RoseGarden
{
public:
    void createRose()
    {
        this->rose = new YellowRose();  // concrete factory method
    }
};

int main()
{
    RoseGarden * garden = NULL;

    garden = new YellowRoseGarden;
    garden->createRose();      // correct factory method is chosen via inheritance
    garden->sayColor();
    delete garden;

    garden = new RedRoseGarden;
    garden->createRose();      // correct factory method is chosen via inheritance
    garden->sayColor();
    delete garden;

    return 1;
}

Also here is a slightly modified version of Abstract Factory to better show how it is used. Just added a house object. Note I changed all your "string" objects to const char* for my compiler.

// make different types of fridges
class IFridge
{
public:
    virtual const char* Run(void) = 0;
};

class FridgeSamsung : public IFridge
{
public:
    const char* Run(void)
    {
        return "This house has a Samsung Fridge\n";
    }
};

class FridgeWhirlpool : public IFridge
{
public:
    const char* Run(void)
    {
        return "This house has a Whirlpool Fridge\n";
    }
};

// make different types of washing machine 
class IWashingMachine
{
public:
    virtual const char*  Run(void) = 0;
};

class WashingMachineSamsung : public IWashingMachine
{
public:
    const char* Run(void)
    {
        return "This house has a Samsung Washing Machine\n";
    }
};

class WashingMachineWhirlpool : public IWashingMachine
{
public:
    const char* Run(void)
    {
        return "This house has a Whirlpool Washing Machine\n";
    }
};

// make different type of factory
class IFactory
{
public:
    virtual IFridge* GetFridge(void) = 0;
    virtual IWashingMachine* GetWashingMachine(void) = 0;
};

class FactorySamsung : public IFactory
{
    IFridge* GetFridge(void)
    {
        return new FridgeSamsung();
    }

    IWashingMachine* GetWashingMachine(void)
    {
        return new WashingMachineSamsung();
    }
};

class FactoryWhirlpool : public IFactory
{
    IFridge* GetFridge(void)
    {
        return new FridgeWhirlpool();
    }

    IWashingMachine* GetWashingMachine(void)
    {
        return new WashingMachineWhirlpool();
    }
};

// Make a house object that has a fridge and a washing machine
class House
{
private:
    class  IWashingMachine * washingMachine;
    class  IFridge * fridge;

public:
    House(IFactory * houseFactory) {
        washingMachine = houseFactory->GetWashingMachine();
        fridge = houseFactory->GetFridge();
    }
    void showAppliances() {
        cout << washingMachine->Run();
        cout << fridge->Run();
    }
};

int main()
{
    class IFactory * factory;  
    class House * house;       

    // make a samsung house
    factory = new FactorySamsung;
    house = new House(factory);     // passing the factory by injection
    house->showAppliances();        // now we have a Samsung house
    cout << '\n';

    // clean up
    delete house;
    delete factory;

    // make a whirlpool house
    factory = new FactoryWhirlpool;
    house = new House(factory);    // passing the factory by injection
    house->showAppliances();       // now we have a WHilepool house
    cout << '\n';

    // clean up
    delete house;
    delete factory;

    return 1;
} 
bcperth
  • 2,191
  • 1
  • 10
  • 16
  • if possible can you please re structure the Factory Method code above to use inheritance – Deepak Jul 20 '18 at 05:22
  • sure - I usually work in JS/PHP so will take a little while to set up. I have some PHP examples to hand if you can read PHP? – bcperth Jul 20 '18 at 09:32
  • sorry not familiar with JS/PHP,if you find any link that points out the above in C++ please share the link. – Deepak Jul 20 '18 at 10:02
  • OK I am used to jumping from one language to the other! I can easily translate above to C++ but will do it tomorrow :-) – bcperth Jul 20 '18 at 10:36
  • thank you very much,i understood about the inheritance in factory method.In case of Abstract Factory method is that _House class_ really required? – Deepak Jul 21 '18 at 13:49
  • Now one more question arrives in my mind about design pattern.Can _Design pattern_ be modified according to our convenience? Don't they have any fixed format to follow? – Deepak Jul 21 '18 at 13:52
  • The main benefit of design patterns is that they provide solutions to frequently occurring situations, in a way that lots of people understand. So when your comments say "...using Factory Method" then that is enough. On the other hand, you can vary the pattern as you like, provided you comment what you did and what is the reason. – bcperth Jul 22 '18 at 23:23
  • Regarding the House Class, this is just to show one of the ways that Abstract Factory is commonly used. Sub-classes of a base "Client" class can be instantiated with different Factory objects according to their reed. In our case "House" is the client (although in my example, I did not sub-class it). The UML diagram at Wiki (https://en.wikipedia.org/wiki/Abstract_factory_pattern) shows the role of the "client" and its sub-classes. – bcperth Jul 22 '18 at 23:37