工厂模式分为三类:简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式
特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。
比如一家生产肥皂的工厂,它只有一家工厂,能够生产两种形状的白色肥皂,客户需要什么形状的,需要显示告诉工厂。
UML
#include
enum EShape
{
ERECTANGLE,
EELLIPSE,
};
class IWhiteSoap
{
public:
IWhiteSoap() {}
virtual ~IWhiteSoap() {}
virtual void show() = 0;
};
class CRectangleWhiteSoap : public IWhiteSoap
{
public:
CRectangleWhiteSoap() {}
~CRectangleWhiteSoap() {}
void show() override
{
std::cout << "produce rectangle white soap" << '\n';
}
};
class CEllipseWhiteSoap : public IWhiteSoap
{
public:
CEllipseWhiteSoap() {}
~CEllipseWhiteSoap() {}
void show() override
{
std::cout << "prodece ellipse white soap" << '\n';
}
};
class CFactory
{
public:
CFactory() {}
~CFactory() {}
IWhiteSoap* createSoap(enum EShape shape)
{
switch (shape)
{
case ERECTANGLE:
return new CRectangleWhiteSoap();
break;
case EELLIPSE:
return new CEllipseWhiteSoap();
break;
default:
return nullptr;
break;
}
}
};
int main()
{
CFactory f;
IWhiteSoap* p1 = f.createSoap(ERECTANGLE);
p1->show();
IWhiteSoap* p2 = f.createSoap(EELLIPSE);
p2->show();
delete p1;
delete p2;
return 0;
}
工厂方法模式
简单工厂的缺点就是,当需要增加新的形状时,需要修改工厂类,这就违背了开放封闭原则。工厂方法可以解决这个问题。工厂方法模式就是,定义一个用于创建对象的接口,让子类决定实例化哪个类。
肥皂工厂从一个工厂变成了两个工厂,一个专门生产矩形的肥皂,一个专门生产椭圆形的肥皂。如果要增加新的形状,就需要增加新的工厂
UML
#include
enum EShape
{
ERECTANGLE,
EELLIPSE,
};
class IWhiteSoap
{
public:
IWhiteSoap() {}
virtual ~IWhiteSoap() {}
virtual void show() = 0;
};
class CRectangleWhiteSoap : public IWhiteSoap
{
public:
CRectangleWhiteSoap() {}
~CRectangleWhiteSoap() {}
void show() override
{
std::cout << "produce rectangle white soap" << '\n';
}
};
class CEllipseWhiteSoap : public IWhiteSoap
{
public:
CEllipseWhiteSoap() {}
~CEllipseWhiteSoap() {}
void show() override
{
std::cout << "prodece ellipse white soap" << '\n';
}
};
class IFactory
{
public:
IFactory() {}
virtual ~IFactory() {}
virtual IWhiteSoap* createWhiteSoap() = 0;
};
class CFactoryRectangle : public IFactory
{
public:
CFactoryRectangle() {}
~CFactoryRectangle() {}
IWhiteSoap* createWhiteSoap() override
{
std::cout << "in Factory rectangle" << '\n';
return new CRectangleWhiteSoap();
}
};
class CFactoryEllipse : public IFactory
{
public:
CFactoryEllipse() {}
~CFactoryEllipse() {}
IWhiteSoap* createWhiteSoap() override
{
std::cout << "in Factory ellipse" << '\n';
return new CEllipseWhiteSoap();
}
};
int main()
{
IFactory *p = new CFactoryEllipse();
IWhiteSoap* soap = p->createWhiteSoap();
soap->show();
delete p;
delete soap;
return 0;
}
抽象工厂模式
如果这家工厂通过市场调查,发现黄色的肥皂销量很好,计划增加黄色肥皂的生产。简单工厂和工厂方法就无法实现了。这时,可以使用抽象工厂。
抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
优点:
- 封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。
- 可以支持不同类型的产品,使得模式灵活性更强。
- 可以非常方便的使用一族中的不同类型的产品。
缺点:
- 结构过于臃肿,如果产品类型较多或产品族较多,会非常难于管理。
- 每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
以这家工厂为例,还是两个工厂,一个专门生产矩形的白色黄色肥皂,一个专门生产椭圆形的白色黄色肥皂。
UML
#include
class IWhiteSoap
{
public:
IWhiteSoap() {}
virtual ~IWhiteSoap() {}
virtual void show() = 0;
};
class CRectangleWhiteSoap : public IWhiteSoap
{
public:
CRectangleWhiteSoap() {}
~CRectangleWhiteSoap() {}
void show() override
{
std::cout << "produce rectangle white soap" << '\n';
}
};
class CEllipseWhiteSoap : public IWhiteSoap
{
public:
CEllipseWhiteSoap() {}
~CEllipseWhiteSoap() {}
void show() override
{
std::cout << "prodece ellipse white soap" << '\n';
}
};
class IYellowSoap
{
public:
IYellowSoap() {}
virtual ~IYellowSoap() {}
virtual void show() = 0;
};
class CRectangleYellowSoap : public IYellowSoap
{
public:
CRectangleYellowSoap() {}
~CRectangleYellowSoap() {}
void show() override
{
std::cout << "produce rectangle Yellow soap" << '\n';
}
};
class CEllipseYellowSoap : public IYellowSoap
{
public:
CEllipseYellowSoap() {}
~CEllipseYellowSoap() {}
void show() override
{
std::cout << "prodece ellipse Yellow soap" << '\n';
}
};
class IFactory
{
public:
IFactory() {}
virtual ~IFactory() {}
virtual IWhiteSoap* createWhiteSoap() = 0;
virtual IYellowSoap* createYellowSoap() = 0;
};
class CFactoryRectangle : public IFactory
{
public:
CFactoryRectangle() {}
~CFactoryRectangle() {}
IWhiteSoap* createWhiteSoap() override
{
return new CRectangleWhiteSoap();
}
IYellowSoap* createYellowSoap() override
{
return new CRectangleYellowSoap();
}
};
class CFactoryEllipse : public IFactory
{
public:
CFactoryEllipse() {}
~CFactoryEllipse() {}
IWhiteSoap* createWhiteSoap() override
{
return new CEllipseWhiteSoap();
}
IYellowSoap* createYellowSoap() override
{
return new CEllipseYellowSoap();
}
};
int main()
{
IFactory *factory = new CFactoryEllipse();
IWhiteSoap* whitesoap = factory->createWhiteSoap();
IYellowSoap* yellosoap = factory->createYellowSoap();
whitesoap->show();
yellosoap->show();
delete factory;
delete whitesoap;
delete yellosoap;
return 0;
}