2018-09-16 23:50:57
简单工厂模式概述
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
UML类图如下:
该模式中包含的角色及其职责(摘自 :百度百科)
工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
优点:
产品的者只需要消费工厂的使用者,而不用关心这些类是如何组织的,如何创建的。所以工厂类是整个模式的核心。简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对客户端来说去除了与具体产品的依赖。
缺点:
优于类对象的全部创建逻辑集中在了同一个类里,所以它只能适用于已经考虑好的类。如果有新的类要加入,那么必须要修改工厂类,这违背了开闭原则。
应用场景:
客户知道传入工厂类的参数,使用工厂类的产品。适用于工厂创建的实例比较少的情况。
知识储备
简单工厂模式是利用继承来实现的(继承里的虚函数、纯虚函数的底层实现,在其它部分写学习体会)。C++里没有接口的概念,但是可以使用虚基类来模仿接口,虚基类的作用就是告诉它的继承者有哪些接口你必须要实现,那么什么叫虚基类了,包含有形如:virtual retType functionName() = 0(这就是纯虚函数);的声明的类就叫做虚基类,如果方法被这样声明,那么意味着它的继承者必须要实现virtual retType functionName() 这个方法。当然也可以声明:virtual retType functionName(){}(虚函数)这样的方法,它不是必须要在子类中实现的。另外,注意析构函数必须是virtual的,这是为了在销毁对象时能正确的知道应该调用哪个类的析构函数。我这里说的虚基类就是在概述中提到的工厂,虚基类的子类就是流水线。那么同样的在生产产品时,为了实现产品的产品族形式生产,那么产品也该有这样一个继承体系。
代码实现
产品类的虚基类:
#ifndef ABSTRACTPRODUCT_H_ #define ABSTRACTPRODUCT_H_ #include <string> class AbstractProduct { public: virtual void setName(const std::string &strName) =0; virtual const std::string& getName() const =0; AbstractProduct() = default; virtual ~AbstractProduct() = default; }; #endif
两个示例产品
#ifndef PRODUCTA_H_ #define PRODUCTA_H_ #include "AbstractProduct.h" class ProductA : public AbstractProduct { private: std::string m_strName; public: void setName(const std::string &strName) { m_strName = strName; } const std::string& getName() const { return m_strName; } ProductA() = default; ~ProductA() = default; }; #endif
#ifndef PRODUCTB_H_ #define PRODUCTB_H_ #include "AbstractProduct.h" class ProductB : public AbstractProduct { private: std::string m_strName; public: void setName(const std::string &strName) { m_strName = strName; } const std::string& getName() const { return m_strName; } ProductB() = default; ~ProductB() = default; }; #endif
工厂类示例:
#ifndef SIMPLEFACTORT_H_ #define SIMPLEFACTORY_H_ enum ProductType { A, B }; #include "AbstractProduct.h" #include "ProductA.h" #include "ProductB.h" class SimpleFactory { public: AbstractProduct* createProduct(const int Type); SimpleFactory() = default; ~SimpleFactory() = default; }; #endif
#include "SimpleFactory.h" AbstractProduct* SimpleFactory::createProduct(const int iType) { AbstractProduct* retObj = nullptr; switch(iType) { case ProductType::A: { retObj = new ProductA(); } break; case ProductType::B: { retObj = new ProductB(); } break; default: break; } return retObj; }
主函数:
#include "SimpleFactory.h" #include <iostream> using namespace std; int main(int argc,char *argv[]) { SimpleFactory objSimpleFactory; auto objRet1 = objSimpleFactory.createProduct(0); std::string strName1 = "Name"; objRet1->setName(strName1); std::cout << "Product : " << objRet1->getName() <<std::endl; auto objRet2 = objSimpleFactory.createProduct(1); std::string strNameB = "ProductB"; objRet2->setName(strNameB); std::cout << "Product B: " << objRet2->getName() << std::endl; if(nullptr != objRet1) { delete objRet1; objRet1 = nullptr; } if(nullptr != objRet2) { delete objRet2; objRet2 = nullptr; } return(1); }