工厂模式的核心目的,是为对象的创建提供一个统一的接口,并把具体类的实例化工作延迟到子类中完成。
当系统中涉及的对象种类繁多、创建过程复杂多样时,直接在调用端 new 对象会让代码变得混乱。工厂模式通过约定统一的创建入口,把创建逻辑收敛到专门的角色里,从而提高内聚、降低耦合。
它定义了创建对象的接口,封装了对象的创建过程,使得具体类的实例化工作可以延迟到子类中去实现。
工厂模式的几种常见写法
工厂模式在实现上有好几种形式,下面分别给出示例。
1. 简单的静态接口函数
最基础的形式是在产品类内部提供一个静态创建函数,把构造函数私有化,调用端只能通过静态接口得到对象。
class Product
{
public:
/**
* @brief create a Product
*/
static Product *create()
{
return new Product;
}
private:
Product(){}
};
2. 抽象工厂类创建(一)
把创建接口抽象到独立的工厂类中,由具体工厂子类实现实际的 new 操作,调用端面向抽象工厂编程。
class Product
{
public:
Product(){}
};
class Factory
{
public:
virtual Product * create() = 0;
};
class ProductFactory : public Factory
{
public:
virtual Product *create()override
{
return new Product;
}
};
int main(int argc, char *argv[])
{
Factory * factory = new ProductFactory;
Product* product = factory->create();
system("pause");
return 0;
}
//还可以进一步 对访问权限封装
3. 模板工厂类创建
借助 C++ 模板和模板特化,可以让工厂按照产品类型自动展开对应的创建逻辑,也可以改写成模板函数的特化版本。
class Product
{
public:
void init(){ cout << __FUNCTION__ << endl; };
Product(){}
};
template< class T>
class Factory
{
public:
Factory(){};
virtual T *create();
};
template<>
class Factory<Product>
{
public:
Factory(){};
virtual Product *create()
{
auto ins = new Product;
ins->init();
return ins;
}
};
int main(int argc, char *argv[])
{
auto *factory = new Factory<Product>();
factory->create();
return 0;
}
//也可以用模板函数创建,各自的特化版本
4. 抽象工厂创建(二)
当一个工厂需要生产一整族相关产品时,可以在抽象工厂里定义多个创建接口,由具体工厂一次性给出整族对象的实现。
class Fruit
{
public:
Fruit(){}
};
class Apple :public Fruit
{
public: Apple(){};
};
class Peach :public Fruit
{
public: Peach(){};
};
class Factory
{
public:
virtual Fruit *createApple() = 0;
virtual Fruit *createPeach() = 0;
};
class FruitFactory : public Factory
{
public:
Fruit *createApple()override
{
return new Apple;
}
Fruit *createPeach()override
{
return new Peach;
}
};
int main(int argc, char *argv[])
{
Factory * factory = new FruitFactory;
Fruit* apple = factory->createApple();
Fruit *peach = factory->createPeach();
system("pause");
return 0;
}