工厂模式提供一种创建对象的最佳方法。
在创建对象时不会对客户端暴露创建逻辑,并且是用过使用一个共同的接口来指向新创建的对象。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
解决:解决接口选择问题。
使用:明确的计划不同条件下创建不同实例。
实现:让其子类实现工厂接口,返回的也是一个抽象的产品。
代码:创建过程在其子类执行。
应用实例:1、需要一辆车,直接从工厂提货,而不用去管这两汽车的制作过程以及具体如何实现。
2、需要一部手机,直接从工厂提货,不用管手机制作细节。
优点:1、一个调用者想创建一个对象,只要知道其名称就行。
2、扩展性高,如果需要增加产品,只要扩张一个工厂类就行。
3、屏蔽产品的实现细节,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
注意事项:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
复杂对象适合使用工厂模式,而简单对象,特别是通过new就可完成创建的对象,无需使用工厂模式。
C++实现:
1、创建一个接口:
Shape.h
#pragma once class Shape { public: virtual void draw() = 0; };
2、创建实现接口的实体类:
Circle.h
#pragma once #include<iostream> #include "Shape.h" class Circle :public Shape { public: void draw() { std::cout << "Circle::draw() method." << std::endl; } };
Rectangle.h
#pragma once #include<iostream> #include "Shape.h" class Rectangle :public Shape { public: void draw() { std::cout << "Rectangle::draw() method." << std::endl; } };
Square.h
#pragma once #include<iostream> #include "Shape.h" class Square :public Shape { public: void draw() { std::cout << "Square::draw() method." << std::endl; } };
3、创建一个工程,生成基于给定信息的实体类的对象:
ShapeFactory.h
#pragma once #include <iostream> #include <string> #include "Shape.h" #include "Rectangle.h" #include "Circle.h" #include "Square.h" class ShapeFactory { public: Shape* getShape(std::string shapeType) { if (shapeType == " ") { return NULL; } if (shapeType == "CIRCLE") { return new Circle(); } else if (shapeType == "RECTANGLE") { return new Rectangle(); } else if (shapeType == "SQUARE") { return new Square(); } return NULL; } };
上述方法存在不足,因为new的对象无法delete,所以使用智能指针替代。版本如下:
#pragma once #include <iostream> #include <string> #include <memory> #include "Shape.h" #include "Rectangle.h" #include "Circle.h" #include "Square.h" class ShapeFactory { public: std::unique_ptr<Shape> getShape(std::string shapeType) { if (shapeType == " ") { return nullptr; } if (shapeType == "CIRCLE") { return std::unique_ptr<Circle>(new Circle); } else if (shapeType == "RECTANGLE") { return std::unique_ptr<Rectangle>(new Rectangle); } else if (shapeType == "SQUARE") { return std::unique_ptr<Square>(new Square); } return NULL; } ~ShapeFactory() { std::cout << "调用析构函数!" << std::endl; } };
4、使用该工厂,通过传递类型信息来获取实体类的对象:
FactoryPatternDemo.cpp
#include<iostream> #include "ShapeFactory.h" #include "Shape.h" using namespace std; int main() { ShapeFactory* shapeFactory = new ShapeFactory(); //获取 Circle 的对象,并调用它的 draw 方法 //对象向上转型 Shape* shape1 = shapeFactory->getShape("CIRCLE"); //调用 Circle 的 draw 方法 //多态的体现 shape1->draw(); delete shape1; shape1 = NULL; //获取 Rectangle 的对象,并调用它的 draw 方法 Shape* shape2 = shapeFactory->getShape("RECTANGLE"); //调用 Rectangle 的 draw 方法 shape2->draw(); delete shape2; shape2 = NULL; //获取 Square 的对象,并调用它的 draw 方法 Shape* shape3 = shapeFactory->getShape("SQUARE"); //调用 Square 的 draw 方法 shape3->draw(); delete shape3; shape3 = NULL; delete shapeFactory; shapeFactory = NULL; system("pause"); return 0; }
不知道上述方法中使用delete方法是否正确,如下版本使用智能指针。
#include<iostream> #include "ShapeFactory.h" #include "Shape.h" using namespace std; int main() { unique_ptr<ShapeFactory> shapeFactory = unique_ptr<ShapeFactory>(new ShapeFactory); //获取 Circle 的对象,并调用它的 draw 方法 //对象向上转型 unique_ptr<Shape> shape1 = shapeFactory->getShape("CIRCLE"); //调用 Circle 的 draw 方法 //多态的体现 shape1->draw(); //获取 Rectangle 的对象,并调用它的 draw 方法 unique_ptr<Shape> shape2 = shapeFactory->getShape("RECTANGLE"); //调用 Rectangle 的 draw 方法 shape2->draw(); //获取 Square 的对象,并调用它的 draw 方法 unique_ptr<Shape> shape3 = shapeFactory->getShape("SQUARE"); //调用 Square 的 draw 方法 shape3->draw(); system("pause"); return 0; }
5、实验结果
参考:https://www.runoob.com/design-pattern/factory-pattern.html