CREATIONAL PATTERNS (OOAD)
Creational Patterns:
1) Singleton:
Ensure a class has only one instance and provide a global point of access to it.
{
int int_abc;
static CSingleton* sing;
CSingleton()
{
int_abc = 10;
}
public:
static CSingleton* getInstance()
{
if (sing == nullptr)
sing = new CSingleton();
return sing;
}
void Display()
{
int_abc += 50;
cout << "CSingleton::Display()" << endl;
cout << "int_abc: " << int_abc << endl;
}
};
CSingleton* CSingleton::sing = nullptr;
int main()
{
CSingleton* sing = CSingleton::getInstance();
sing->Display();
}
2) Factory:
Define an interface for creating an object, but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
Example:
class Shape
{
public:
virtual void Draw() = 0;
virtual void Erase() = 0;
};
class Circle : public Shape
{
public:
void Draw()
{
cout << "Circle::Draw()" << endl;
}
void Erase()
{
cout << "Circle::Erase()" << endl;
}
};
class Square : public Shape
{
public:
void Draw()
{
cout << "Square::Draw()" << endl;
}
void Erase()
{
cout << "Square::Erase()" << endl;
}
};
class CFactory
{
public:
virtual Shape* CreateShape() = 0;
};
class CircleFactory : public CFactory
{
public:
Shape* CreateShape()
{
return new Circle;
}
};
class SquareFactory : public CFactory
{
public:
Shape* CreateShape()
{
return new Square;
}
};
void ShapeFactoryFunction()
{
CFactory* FactShapeCircle = new CircleFactory();
Shape* circleShape = FactShapeCircle->CreateShape();
circleShape->Draw();
circleShape->Erase();
CFactory* FactShapeSquare = new SquareFactory();
Shape* squareShape = FactShapeSquare->CreateShape();
squareShape->Draw();
squareShape->Erase();
}3) Abstract Factory:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Example:
class AbstractProductA
{
public:
virtual void func_ProductA() = 0;
};
class ConcreteProductA1 : public AbstractProductA
{
public:
void func_ProductA()
{
cout << "ConcreteProductA1::func_ProductA" << endl;
}
};
class ConcreteProductA2 : public AbstractProductA
{
public:
void func_ProductA()
{
cout << "ConcreteProductA2::func_ProductA" << endl;
}
};
class AbstractProductB
{
public:
virtual void func_ProductB() = 0;
};
class ConcreteProductB1 : public AbstractProductB
{
public:
void func_ProductB()
{
cout << "ConcreteProductB1::func_ProductB" << endl;
}
};
class ConcreteProductB2 : public AbstractProductB
{
public:
void func_ProductB()
{
cout << "ConcreteProductB2::func_ProductB" << endl;
}
};
class AbstractFactory
{
public:
virtual AbstractProductA* Fact_ProductA() = 0;
virtual AbstractProductB* Fact_ProductB() = 0;
};
class ConcreteFactory1 : public AbstractFactory
{
public:
AbstractProductA* Fact_ProductA()
{
cout << "ConcreteFactory1::Fact_ProductA" << endl;
return new ConcreteProductA1;
}
AbstractProductB* Fact_ProductB()
{
cout << "ConcreteFactory1::Fact_ProductB" << endl;
return new ConcreteProductB1;
}
};
class ConcreteFactory2 : public AbstractFactory
{
public:
AbstractProductA* Fact_ProductA()
{
cout << "ConcreteFactory2::Fact_ProductA" << endl;
return new ConcreteProductA2;
}
AbstractProductB* Fact_ProductB()
{
cout << "ConcreteFactory2::Fact_ProductB" << endl;
return new ConcreteProductB2;
}
};
class Client
{
AbstractProductA* ProductA;
AbstractProductB* ProductB;
public:
Client(AbstractFactory* factory)
{
ProductA = factory->Fact_ProductA();
ProductB = factory->Fact_ProductB();
}
void RunClient()
{
ProductA->func_ProductA();
ProductB->func_ProductB();
}
};
void AbsFact_Client()
{
AbstractFactory* abFactory[2];
Client* client_Fact[2];
abFactory[0] = new ConcreteFactory1();
abFactory[1] = new ConcreteFactory2();
client_Fact[0] = new Client(abFactory[0]);
client_Fact[1] = new Client(abFactory[1]);
client_Fact[0]->RunClient();
client_Fact[1]->RunClient();
}
4) Builder:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
Example:
class Product
{
list<string> list_parts;
list<string>::iterator it;
public:
void add(string part)
{
list_parts.push_back(part);
}
void show()
{
for (it = list_parts.begin(); it != list_parts.end(); it++)
{
cout << (*it).c_str() << endl;
}
}
};
class Builder
{
public:
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual Product getProduct() = 0;
};
class ConcreteBuilder1 : public Builder
{
Product firstProduct;
public:
void buildPartA()
{
cout << "ConcreteBuilder1::buildPartA" << endl;
firstProduct.add("PartA");
}
void buildPartB()
{
cout << "ConcreteBuilder1::buildPartB" << endl;
firstProduct.add("PartB");
}
Product getProduct()
{
return firstProduct;
}
};
class ConcreteBuilder2 : public Builder
{
Product secondProduct;
public:
void buildPartA()
{
cout << "ConcreteBuilder2::buildPartA" << endl;
secondProduct.add("PartX");
}
void buildPartB()
{
cout << "ConcreteBuilder2::buildPartB" << endl;
secondProduct.add("PartY");
}
Product getProduct()
{
return secondProduct;
}
};
class Director
{
public:
void Construct(Builder* build)
{
build->buildPartA();
build->buildPartB();
cout << endl;
}
};
void DirectorBuilder()
{
Director director;
Builder* b1 = new ConcreteBuilder1();
Builder* b2 = new ConcreteBuilder2();
director.Construct(b1);
director.Construct(b2);
Product p1 = b1->getProduct();
Product p2 = b2->getProduct();
p1.show();
cout << endl;
p2.show();
}
Specify the kinds of objects to create using a prototypic instance and create new objects by copying this prototype.
Example:
enum RECORD_TYPE
{
CAR,
BIKE,
PERSON
};
class Record
{
public:
Record() {}
~Record() {}
virtual Record* Clone() = 0;
virtual void ChangeVal(string car, int cID) = 0;
virtual void Print() = 0;
};
class CarRecord : public Record
{
string CarName;
int CarID;
public:
CarRecord(string car, int cID) : CarName(car), CarID(cID)
{ }
CarRecord(CarRecord& cRecord)
{
CarName = cRecord.CarName;
CarID = cRecord.CarID;
}
~CarRecord() {}
Record* Clone()
{
return new CarRecord(*this);
}
void ChangeVal(string car, int cID)
{
CarName = car;
CarID = cID;
}
void Print()
{
cout << "Car Record" << endl;
cout << "Car Name : " << CarName << endl;
cout << "Car ID : " << CarID << endl;
}
};
class BikeRecord : public Record
{
string BikeName;
int BikeID;
public:
BikeRecord(string bike, int bID) : BikeName(bike), BikeID(bID)
{ }
BikeRecord(BikeRecord& bRecord)
{
BikeName = bRecord.BikeName;
BikeID = bRecord.BikeID;
}
~BikeRecord() {}
Record* Clone()
{
return new BikeRecord(*this);
}
void ChangeVal(string bike, int bID)
{
BikeName = bike;
BikeID = bID;
}
void Print()
{
cout << "Bike Record" << endl;
cout << "Bike Name : " << BikeName << endl;
cout << "Bike ID : " << BikeID << endl;
}
};
class PersonRecord : public Record
{
string PersonName;
int PersonID;
public:
PersonRecord(string person, int pID) : PersonName(person), PersonID(pID)
{ }
PersonRecord(PersonRecord& pRecord)
{
PersonName = pRecord.PersonName;
PersonID = pRecord.PersonID;
}
~PersonRecord() {}
Record* Clone()
{
return new PersonRecord(*this);
}
void ChangeVal(string person, int pID)
{
PersonName = person;
PersonID = pID;
}
void Print()
{
cout << "Person Record" << endl;
cout << "Person Name: " << PersonName << endl;
cout << "Person ID : " << PersonID << endl;
}
};
class RecordFactory
{
map<RECORD_TYPE, Record*> m_mapRecord;
public:
RecordFactory()
{
m_mapRecord[CAR] = new CarRecord("Ferrari", 5050);
m_mapRecord[BIKE] = new BikeRecord("Yamaha", 2525);
m_mapRecord[PERSON] = new PersonRecord("Tom", 25);
}
~RecordFactory()
{
delete m_mapRecord[CAR];
delete m_mapRecord[BIKE];
delete m_mapRecord[PERSON];
}
Record* CreateRecord(RECORD_TYPE rType)
{
return m_mapRecord[rType]->Clone();
}
};
void RecordFactoryFunction()
{
RecordFactory* RecFactory = new RecordFactory();
Record* pCarRecord;
pCarRecord = RecFactory->CreateRecord(CAR);
pCarRecord->Print();
cout << endl;
delete pCarRecord;
Record* pCarRecord1;
pCarRecord1 = RecFactory->CreateRecord(CAR);
pCarRecord1->ChangeVal("ABCD", 1111);
pCarRecord1->Print();
cout << endl;
delete pCarRecord1;
Record* pBikeRecord;
pBikeRecord = RecFactory->CreateRecord(BIKE);
pBikeRecord->Print();
cout << endl;
delete pBikeRecord;
Record* pBikeRecord1;
pBikeRecord1 = RecFactory->CreateRecord(BIKE);
pBikeRecord1->ChangeVal("EFGH", 2222);
pBikeRecord1->Print();
cout << endl;
delete pBikeRecord1;
Record* pPersonRecord;
pPersonRecord = RecFactory->CreateRecord(PERSON);
pPersonRecord->Print();
cout << endl;
delete pPersonRecord;
Record* pPersonRecord1;
pPersonRecord1 = RecFactory->CreateRecord(PERSON);
pPersonRecord1->ChangeVal("IJKL", 3333);
pPersonRecord1->Print();
cout << endl;
delete pPersonRecord1;
delete RecFactory;
}