factory pattern

1
Factory  react example:

export default class SlideFactory {
static build(data) {
switch (data.source) {
case ‘brand’:
return ;
case ‘article’:
return ;
default:
return undefined;
}
}
}

1
2
3
4
5
6
7
8
```
const items = [
{
source: ‘brand’,
title: ‘title’
}
]
const renderedItems = items.map((item) => SlideFactory.build(item));

the items can have properties for different kinds of slider.

// A design without factory pattern

#include
using namespace std;

// Library classes
class Vehicle {
public:
virtual void printVehicle() = 0;
};
class TwoWheeler : public Vehicle {
public:
void printVehicle() {
cout << “I am two wheeler” << endl;
}
};
class FourWheeler : public Vehicle {
public:
void printVehicle() {
cout << “I am four wheeler” << endl;
}
};

// Client (or user) class
class Client {
public:
Client(int type) {

    // Client explicitly creates classes according to type 
    if (type == 1) 
        pVehicle = new TwoWheeler(); 
    else if (type == 2) 
        pVehicle = new FourWheeler(); 
    else
        pVehicle = NULL; 
} 

~Client()   { 
    if (pVehicle) 
    { 
        delete[] pVehicle; 
        pVehicle = NULL; 
    } 
} 

Vehicle* getVehicle() { 
    return pVehicle; 
} 

private:
Vehicle *pVehicle;
};

// Driver program
int main() {
Client pClient = new Client(1);
Vehicle
pVehicle = pClient->getVehicle();
pVehicle->printVehicle();
return 0;
}

1
2
3
4
5
6
7
8
 What is the problems with above design?
As you must have observed in the above example, Client creates objects of either TwoWheeler or FourWheeler based on some input during constructing its object.
Say, library introduces a new class ThreeWheeler to incorporate three wheeler vehicles also. What would happen? Client will end up chaining a new else if in the conditional ladder to create objects of ThreeWheeler. Which in turn will need Client to be recompiled. So, each time a new change is made at the library side, Client would need to make some corresponding changes at its end and recompile the code. Sounds bad? This is a very bad practice of design.



How to avoid the problem?
The answer is, create a static (or factory) method. Let us see below code.

// C++ program to demonstrate factory method design pattern

#include
using namespace std;

enum VehicleType {
VT_TwoWheeler, VT_ThreeWheeler, VT_FourWheeler
};

// Library classes
class Vehicle {
public:
virtual void printVehicle() = 0;
static Vehicle* Create(VehicleType type);
};
class TwoWheeler : public Vehicle {
public:
void printVehicle() {
cout << “I am two wheeler” << endl;
}
};
class ThreeWheeler : public Vehicle {
public:
void printVehicle() {
cout << “I am three wheeler” << endl;
}
};
class FourWheeler : public Vehicle {
public:
void printVehicle() {
cout << “I am four wheeler” << endl;
}
};

// Factory method to create objects of different types.
// Change is required only in this function to create a new object type
Vehicle* Vehicle::Create(VehicleType type) {
if (type == VT_TwoWheeler)
return new TwoWheeler();
else if (type == VT_ThreeWheeler)
return new ThreeWheeler();
else if (type == VT_FourWheeler)
return new FourWheeler();
else return NULL;
}

// Client class
class Client {
public:

// Client doesn't explicitly create objects 
// but passes type to factory method "Create()" 
Client() 
{ 
    VehicleType type = VT_ThreeWheeler; 
    pVehicle = Vehicle::Create(type); 
} 
~Client() { 
    if (pVehicle) { 
        delete[] pVehicle; 
        pVehicle = NULL; 
    } 
} 
Vehicle* getVehicle()  { 
    return pVehicle; 
} 

private:
Vehicle *pVehicle;
};

// Driver program
int main() {
Client pClient = new Client();
Vehicle
pVehicle = pClient->getVehicle();
pVehicle->printVehicle();
return 0;
}
`

In the above example, we have totally decoupled the selection of type for object creation from Client. The library is now responsible to decide which object type to create based on an input. Client just needs to make call to library’s factory Create method and pass the type it wants without worrying about the actual implementation of creation of objects.