C ++ Design Patterns: Abstract Factory pattern

Abstract Factory (Abstract Factory Pattern) is to create a model for other factories around a super plant. The super plant, also known as plant factory.

Introduction

Intent: to provide a series of related or dependent objects to create interfaces without specifying their concrete classes.

Mainly to solve: the main problem of interface options.

When to use: System products have more than one product family, and the only system in which a family of consumer products.

How to solve: in a product family inside, define multiple products.

The key code: aggregating multiple similar products in a factory.

Application examples: work, in order to take part in some meetings, there must be two or more sets of clothes it with, say, business attire (complete sets, a series of specific products), fashion dress (complete sets, a series of specific products), even for a family it may have business women, business men's, women's fashion, men's fashion, these are also the set of that series of specific products. A case is assumed (in reality does not exist, or else, not communism, but is conducive to explain the abstract factory pattern), in your home, one wardrobe (concrete plant) can only store a certain kind of like this clothes (complete sets, a series of specific product), every time you get this set of clothes from the closet naturally took out. With OOP thinking to understand, all the wardrobe (concrete plant) are the class of wardrobe (abstract factory) one, and each one set of clothes and including specific jacket (a particular product), pants (a specific product), which in fact are the specific jacket coat (abstract products), specific pants are pants (another abstract product).

Pros: When a product family of multiple objects are designed to work together when it guarantees clients always use only objects in the same product family.

Disadvantages: product family expansion is very difficult, to increase a product of a series, both in the abstract Creator Riga codes, but also add specific code inside.

Usage scenarios:  1, QQ for the skin, a set of change together. 2, generate different procedures of the operating system.

Note: The product family is difficult to expand, easy to expand the product level.

æ½è ± ¡To · ¥ å模å¼ç UML å¾

 code show as below:

shape.h

#pragma once
class Shape
{
public:
	Shape();
	~Shape();
	virtual void draw() = 0;
};

class Circle :public Shape
{
public:
	Circle();
	~Circle() {};
	virtual void draw() override;
};

class Square :public Shape
{
public:
	Square();
	~Square() {};
	virtual void draw() override;
};

class Rectangle :public Shape
{
public:
	Rectangle();
	~Rectangle() {};
	virtual void draw() override;
};

shape.cpp

#include "Shape.h"
#include <iostream>
using namespace std;


Shape::Shape()
{
}


Shape::~Shape()
{
}

Circle::Circle() :Shape()
{
}

void Circle::draw()
{
	cout << "Circle::draw()\n";
}

Square::Square() :Shape()
{
}

void Square::draw()
{
	cout << "Square::draw()\n";
}

Rectangle::Rectangle() :Shape()
{
}

void Rectangle::draw()
{
	cout << "Rectangle::draw()\n";
}

color.h

#pragma once

class Color
{
public:
	Color();
	~Color();
	virtual void fill() = 0;
};

class Red :public Color
{
public:
	Red() :Color() {}
	~Red() {}
	virtual void fill();
};

class Green :public Color
{
public:
	Green() :Color() {}
	~Green() {}
	virtual void fill();
};

class Blue :public Color
{
public:
	Blue() :Color() {}
	~Blue() {}
	virtual void fill();
};

color.cpp

#include "Color.h"
#include <iostream>
using namespace std;


Color::Color()
{
}


Color::~Color()
{
}

void Red::fill()
{
	cout << "Red::fill()\n";
}

void Green::fill()
{
	cout << "Green::fill()\n";
}

void Blue::fill()
{
	cout << "Bule::fill()\n";
}

abstractFactory.h

#pragma once
class Shape;
class Color;

enum ShapeType
{
	CIRCLE_TYPE,
	SQUARE_TYPE,
	RECTANGLE_TYPE
};

enum ColorType
{
	RED_TYPE,
	GREEN_TYPE,
	BLUE_TYPE
};
class AbstractFactory
{
public:
	AbstractFactory();
	~AbstractFactory();
	virtual Shape *getShape(ShapeType shapeType) = 0;
	virtual Color *getColor(ColorType colorType) = 0;
};

class ShapeFactory :public AbstractFactory
{
public:
	ShapeFactory() :AbstractFactory() {}
	~ShapeFactory() {}
	 Shape *getShape(ShapeType shapeType);
	 Color *getColor(ColorType colorType) { return nullptr; }
};

class ColorFactory :public AbstractFactory
{
public:
	ColorFactory() :AbstractFactory() {}
	~ColorFactory() {}
	Shape *getShape(ShapeType shapeType) { return nullptr; };
	Color *getColor(ColorType colorType);
};

abstractFactory.cpp

#include "AbstractFactory.h"
#include "Shape.h"
#include "Color.h"


AbstractFactory::AbstractFactory()
{
}


AbstractFactory::~AbstractFactory()
{
}

Shape * ShapeFactory::getShape(ShapeType shapeType)
{
	if (shapeType == CIRCLE_TYPE)
	{
		return new Circle();
	}
	else if (shapeType == SQUARE_TYPE)
	{
		return new Square();
	}
	else if (shapeType == RECTANGLE_TYPE)
	{
		return new Rectangle();
	}
	else
	{
		return nullptr;
	}
}

Color * ColorFactory::getColor(ColorType colorType)
{
	if (colorType == RED_TYPE)
	{
		return new Red();
	}
	else if (colorType == GREEN_TYPE)
	{
		return new Green();
	}
	else if (colorType == BLUE_TYPE)
	{
		return new Blue();
	}
	else
	{
		return nullptr;
	}
}

FactoryProducer.h

#pragma once
class AbstractFactory;

enum FactoryType
{
	SHAPE_TYPE,
	COLOR_TYPE
};

class FactoryProducer
{
public:
	FactoryProducer();
	~FactoryProducer();
	AbstractFactory * getFactory(FactoryType factoryType);
};

FactoryProducer.cpp

#include "FactoryProducer.h"
#include "AbstractFactory.h"


FactoryProducer::FactoryProducer()
{
}


FactoryProducer::~FactoryProducer()
{
}

AbstractFactory * FactoryProducer::getFactory(FactoryType factoryType)
{
	if (factoryType == SHAPE_TYPE)
	{
		return new ShapeFactory();
	}
	else if (factoryType == COLOR_TYPE)
	{
		return new ColorFactory();
	}
	else
		return nullptr;
}

main.cpp

#include "Shape.h"
#include "Color.h"
#include "AbstractFactory.h"
#include "FactoryProducer.h"
#include <iostream>
using namespace std;

int main()
{
	FactoryProducer *pFactoryProducer = new FactoryProducer;
	AbstractFactory *pAbstractFactory1 = pFactoryProducer->getFactory(SHAPE_TYPE);
	Shape *pShape1 = pAbstractFactory1->getShape(CIRCLE_TYPE);
	pShape1->draw();
	Shape *pShape2 = pAbstractFactory1->getShape(SQUARE_TYPE);
	pShape2->draw();
	Shape *pShape3 = pAbstractFactory1->getShape(RECTANGLE_TYPE);
	pShape3->draw();

	AbstractFactory *pAbstractFactory2 = pFactoryProducer->getFactory(COLOR_TYPE);
	Color *pColor1 = pAbstractFactory2->getColor(RED_TYPE);
	pColor1->fill();
	Color *pColor2 = pAbstractFactory2->getColor(GREEN_TYPE);
	pColor2->fill();
	Color *pColor3 = pAbstractFactory2->getColor(BLUE_TYPE);
	pColor3->fill();

	delete pColor3;
	delete pColor2;
	delete pColor1;
	delete pAbstractFactory2;
	delete pShape3;
	delete pShape2;
	delete pShape1;
	delete pAbstractFactory1;
	delete pFactoryProducer;
	int d;
	cin >> d;
	return 0;
}

Output:

Circle::draw()
Square::draw()
Rectangle::draw()
Red::fill()
Green::fill()
Bule::fill()

 

Published 257 original articles · won praise 22 · views 90000 +

Guess you like

Origin blog.csdn.net/qq_24127015/article/details/105288869