设计模式(三)——工厂方法模式
模式动机
工厂方法模式本质上与前面所说的简单工厂模式没什么太大区别,但需要注意的一点是,简单工厂模式部分不符合开闭原则,每次添加新的ConcreteProduct对象就要去修改创建Product的逻辑,这点已经不满足开闭原则了。工厂方法模式则弥补了这个缺陷,它将Factory抽象出来,使ConcreteFactory继承于Factory,每次要添加一个ConcreteProduct,只需要添加相应的ConcreteFactory类就行了,不用修改Factory的代码逻辑。
模式定义
工厂方法模式(Factory Method Pattern),也叫工厂模式,它属于创建型模式。在工厂模式中,Factory负责定义创建对象的公共接口,而ConcreteFactory负责实现创建ConcreteProduct的代码,将创建过程延迟到了派生类中进行,即通过ConcreteFactory来决定到底创建哪个Product。
模式结构
Product: 抽象产品;
ConcreteProduct: 具体产品;
Factory: 抽象工厂;
ConcreteFactory: 具体工厂。
模式分析
工厂方法模式是简单工厂模式的简单扩展,通过抽象出Factory,将ConcreteProduct的实例化延迟到派生类,来解决简单工厂模式不满足开闭原则的缺点。并且进一步提升扩展性,添加新的ConcreteProduct仅需添加对应的ConcreteFactory即可,不需要修改Factory创建逻辑。
模式实例——Shape、Circle、Rectangle、ShapeFactory、CircleFactory、RectangleFactory
类图:
//Shape类、Circle类、Rectangle类
class Shape {
public:
virtual void Draw() {
std::cout << "Draw a Shape whatever is which one." << std::endl;
}
Shape() { }
virtual ~Shape() { }
};
class Circle : public Shape {
public:
virtual void Draw() {
std::cout << "Draw a Circle." << std::endl;
}
Circle() : Shape() { }
virtual ~Circle() { }
};
class Rectangle : public Shape {
public:
virtual void Draw() {
std::cout << "Draw a Rectangle." << std::endl;
}
Rectangle() : Shape() { }
virtual ~Rectangle() { }
};
//ShapeFactory类、CircleFactory类、RectangleFactory类
class ShapeFactory {
public:
virtual Shape *GetShape() {
return new Shape();
}
ShapeFactory() { }
~ShapeFactory() { }
};
class CircleFactory : public ShapeFactory {
public:
virtual Shape *GetShape() {
return new Circle();
}
CircleFactory() : ShapeFactory() { }
virtual ~CircleFactory() { }
};
class RectangleFactory : public ShapeFactory {
public:
virtual Shape *GetShape() {
return new Rectangle();
}
RectangleFactory() : ShapeFactory() { }
virtual ~RectangleFactory() { }
};
以上就是工厂方法模式的简单使用示意,添加新的ConcreteShape,只需相应地继承ShapeFactory添加新的ConcreteFactory即可。
工厂方法模式优点
- 具有简单工厂模式的优点,同时又弥补了简单工厂模式不满足开闭原则的缺点。
工厂方法模式缺点
- 扩展时,需要增加类的数量,造成整个系统结构更加复杂难以理解。