定义
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
使用场景
- 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
- 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制"来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
结构
代码示例
//AbstractFactory.h
/****************************************************/
#ifndef ABSTRACT_FACTORY_H
#define ABSTRACT_FACTORY_H
#include<iostream>
using namespace std;
//形状抽象类接口shape
class shape
{
public:
shape() {};
virtual ~shape() {};
virtual void draw() = 0;
virtual double get_area() = 0;
virtual void calculate_area() = 0;
enum shape_type {rectangle,circle};
protected:
double area;
};
//继承形状抽象接口的三角形类rectangle
class rectangle :shape
{
public:
rectangle() { h = 2.5; k = 3.6; area = 0; };
~rectangle() {};
void draw();
double get_area();
void calculate_area();
private:
double h;
double k;
};
void rectangle::draw()
{
cout << "draw rectangle class" << endl;
}
double rectangle::get_area()
{
return area;
}
void rectangle::calculate_area()
{
area = h*k / 2;
}
//继承形状抽象接口的圆形类circle
class circle :shape
{
public:
circle() { r = 4.8; area = 0; };
~circle() {};
void draw();
double get_area();
void calculate_area();
private:
double r;
};
void circle::draw()
{
cout << "draw circle class" << endl;
}
double circle::get_area()
{
return area;
}
void circle::calculate_area()
{
area = 3.14*r*r;
}
//颜色抽象类接口color
class color
{
public:
color() {};
virtual ~color() {};
virtual void fill()=0;
enum color_type { red, green };
};
//继承颜色抽象类的红色类red
class red :color
{
public:
red() {};
~red() {};
void fill() { cout << "fill red color" << endl; };
};
//继承颜色抽象类的绿色类green
class green :color
{
public:
green() {};
~green() {};
void fill() { cout << "fill green color" << endl; };
};
//抽象类工厂abstractfactory
class abstractfactory
{
public:
abstractfactory() {};
virtual ~abstractfactory() {};
virtual shape* getshape(shape::shape_type type)=0;
virtual color* getcolor(color::color_type type)=0;
enum factory_type{tshape,tcolor};
};
//继承抽象工厂的形状工厂shapefactory
class shapefactory:abstractfactory
{
public:
shapefactory() {};
virtual ~shapefactory() {};
shape* getshape(shape::shape_type type);
color* getcolor(color::color_type type) { return NULL; };
};
shape* shapefactory::getshape(shape::shape_type type)
{
switch (type)
{
case shape::rectangle:
return (shape*)new rectangle();
case shape::circle:
return (shape*)new circle();
default:
return NULL;
}
}
//继承抽象工厂的颜色工厂colorfactory
class colorfactory :abstractfactory
{
public:
colorfactory() {};
virtual ~colorfactory() {};
shape* getshape(shape::shape_type type) { return NULL; };
color* getcolor(color::color_type type);
};
color* colorfactory::getcolor(color::color_type type)
{
switch (type)
{
case color::red:
return (color*)new red();
case color::green:
return (color*)new green();
default:
return NULL;
}
}
//工厂创造器类factoryproduct,通过传递颜色或形状信息来获取工厂
class factoryproduct
{
public:
factoryproduct() {};
~factoryproduct() {};
abstractfactory* getfactory(abstractfactory::factory_type type);
};
abstractfactory* factoryproduct::getfactory(abstractfactory::factory_type type)
{
switch (type)
{
case abstractfactory::tshape:
return (abstractfactory*)new shapefactory();
case abstractfactory::tcolor:
return (abstractfactory*)new colorfactory();
default:
return NULL;
}
}
#endif
//test.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "AbstractFactory.h"
int main()
{
factoryproduct facput;
abstractfactory *slfactory = facput.getfactory(abstractfactory::tshape);
shape *k1 = slfactory->getshape(shape::rectangle);
k1->draw();
k1->calculate_area();
cout << "area: " << k1->get_area() << endl;
shape *k2 = slfactory->getshape(shape::circle);
k2->draw();
k2->calculate_area();
cout << "area: " << k2->get_area() << endl;
delete slfactory;
slfactory = NULL;
delete k1;
k1 = NULL;
delete k2;
k2 = NULL;
slfactory = facput.getfactory(abstractfactory::tcolor);
color *k3 = slfactory->getcolor(color::red);
k3->fill();
color *k4 = slfactory->getcolor(color::green);
k4->fill();
delete slfactory;
slfactory = NULL;
delete k3;
k3 = NULL;
delete k4;
k4 = NULL;
return 0;
}
运行结果
要点总结
- 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工广完全可以。
- “系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
- Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。