抽象工厂模式(Abstract Factory)
动机(Motivation)
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
模式定义
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。 ——《设计模式》GoF
结构(Struture)
实例
//步骤1 为形状创建一个接口
class Shape
{
public:
virtual void draw() = 0;
};
//步骤2 创建实现形状接口的实体类
class Circle : public Shape
{
public:
void draw()
{
cout << "Inside Circle::draw() method." << endl;
}
};
class Square : public Shape
{
public:
void draw()
{
cout << "Inside Square::draw() method." << endl;
}
};
class Rectangle : public Shape
{
public:
void draw()
{
cout << "Inside Rectangle::draw() method." << endl;
}
};
//步骤3 为颜色创建一个接口
class Color
{
public:
virtual void fill() = 0;
};
//步骤4 创建实现颜色接口的实体类
class Red : public Color
{
public:
void fill()
{
cout << "Inside Red::fill() method." << endl;
}
};
class Green : public Color
{
public:
void fill()
{
cout << "Inside Green::fill() method." << endl;
}
};
class Blue : public Color
{
public:
void fill()
{
cout << "Inside Blue::fill() method." << endl;
}
};
//步骤5 为 Color 和 Shape 对象创建抽象类来获取工厂
class AbstractFactory
{
public:
virtual Shape* getShape(string shapeType) = 0;
virtual Color* getColor(string color) = 0;
};
//步骤6 创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象
class ShapeFactory : public AbstractFactory
{
public:
Shape* getShape(string shapeType)
{
if ( shapeType == "CIRCLE" )
return new Circle;
else if ( shapeType == "SQUARE" )
return new Square;
else if ( shapeType == "RECTANGLE" )
return new Rectangle;
else
{
cout << "未知的shapeType" << endl;
return NULL;
}
}
Color* getColor(string color)
{
return NULL;
}
};
class ColorFactory : public AbstractFactory
{
public:
Shape* getShape(string shapeType)
{
return NULL;
}
Color* getColor(string color)
{
if ( color == "RED" )
return new Red;
else if ( color == "GREEN" )
return new Green;
else if ( color == "BLUE" )
return new Blue;
else
{
cout << "未知的color" << endl;
return NULL;
}
}
};
//步骤7 创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂
class FactoryProducer
{
public:
AbstractFactory* getFactory(string choice)
{
if ( choice == "SHAPE" )
return new ShapeFactory;
else if ( choice == "COLOR" )
return new ColorFactory;
else
{
cout << "未知的choice" << endl;
return NULL;
}
}
};
//步骤8 使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象
void main()
{
FactoryProducer *factoryProducer = NULL;
AbstractFactory *factory = NULL;
Shape *shape = NULL;
Color *color = NULL;
factoryProducer = new FactoryProducer;
//获取形状工厂
factory = factoryProducer->getFactory("SHAPE");
//获取形状为 Circle 的对象
shape = factory->getShape("CIRCLE");
//调用 Circle 的 draw 方法
shape->draw();
//删除 Circle 对象
delete shape;
//获取形状为 Square 的对象
shape = factory->getShape("SQUARE");
//调用 Square 的 draw 方法
shape->draw();
//删除 Square 对象
delete shape;
//获取形状为 Rectangle 的对象
shape = factory->getShape("RECTANGLE");
//调用 Rectangle 的 draw 方法
shape->draw();
//删除 Rectangle 对象
delete shape;
//删除形状工厂
delete factory;
//获取颜色工厂
factory = factoryProducer->getFactory("COLOR");
//获取颜色为 Red 的对象
color = factory->getColor("RED");
//调用 Red 的 fill 方法
color->fill();
//删除 Red 对象
delete color;
//获取颜色为 Green 的对象
color = factory->getColor("GREEN");
//调用 Green 的 fill 方法
color->fill();
//删除 Green 对象
delete color;
//获取颜色为 Blue 的对象
color = factory->getColor("BLUE");
//调用 Blue 的 fill 方法
color->fill();
//删除 Blue 对象
delete color;
delete factoryProducer;
delete factory;
//delete shape;
//delete color;
system("pause");
}
优缺点
优点: 工厂抽象类创建了多个类型的产品,当有需求时,可以创建相关产品子类和子工厂类来获取。
缺点: 扩展新种类产品时困难。抽象工厂模式需要我们在工厂抽象类中提前确定了可能需要的产品种类,以满足不同型号的多种产品的需求。但是如果我们需要的产品种类并没有在工厂抽象类中提前确定,那我们就需要去修改工厂抽象类了,而一旦修改了工厂抽象类,那么所有的工厂子类也需要修改, 这样显然扩展不方便。
要点总结
-
如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。
-
“系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
-
Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。