什么是工厂模式?
工厂模式是23种GOF设计模式之一,在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
由以下两个问题引入工厂模式:
所以工厂模式的两个重要功能是:
- 定义创建对象的接口,封装了对象的创建;
- 使得具体化类的工作延迟到子类;
了解一下工厂家族里的简单工厂(静态工厂)模型,工厂方法模型,抽象工厂模型
简单工厂模型
简单工厂模式当然是相比而言最简单的,形象的讲,这是一家由老板一个人经营的面馆(只卖面),他们家卖泡面,拉面,拌面。老板一个人要做饭洗碗收钱,很累。
工厂方法模式
工厂方法模式和简单工厂模式相比,这家面馆老板聪明了点,雇了店员去做饭洗碗,老板只需要告诉店员去干嘛就好了,在其他方面没有改动,还是卖那些面。
抽象工厂模式
抽象工厂模式和工厂方法模式相比,这家老板更会经营了,他们家不仅卖面,还会卖各种饮料。
好了现在可以很正经的介绍这些模式了。。。。。。。
简单工厂模式属于创建型模式(当然整个工厂模式家族都属于创建型模式),又叫做静态工厂方法模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一种特殊实现。
工厂方法模式,又称为多态性模式。在工厂方法模式中,核心的工厂类不再负责所有的产品创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
了解了这么多后,会过来再看看工厂模式,它其实就是一种实例化对象模式,相当于创建实例对象的new。由于构建同产品类型(继承同一基类)的不同对象时,这些对象new很复杂,需要很多参数,而这些参数大部分又是固定的,所以就引入了工厂模式
三种模式之间的关系
大部分抽象工厂模式都是这样的:它的里面是一堆工厂方法,每个工厂方法返回某种类型的对象。
如果说抽象工厂中的工厂是一个实际的工厂的话,那么工厂方法中的工厂更像现实中工厂的一条生产线
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。
工厂方法模式与简单工厂模式的区别:
可以看出,普通工厂模式特点:不仅仅做出来的产品要抽象, 工厂也应该需要抽象。
看懂了吗????????
其实说白了就是一句话:简单工厂模式没有对工厂抽象化,工厂方法模式只有一个抽象工厂,而抽象工厂模式可以抽象多个工厂
工厂模式的作用
工厂模式的应用实现了代码的高内聚低耦合,其中定义了创建子类对象的接口,封装了子类对象的创建过程,这样我们就不用每次都辛苦的写一堆实例化子类对象的提前操作。
工厂模式的应用也使实例化子类对象的操作延迟到了子类中,因为只有在子类中可以决定到底实例化哪一个类
代码实现
#include <iostream>
#include<vector>
using namespace std;
/*简单工厂模型*/
//产品父类
class IProduct
{
public:
virtual ~IProduct() = 0;
protected:
IProduct() {};
};
IProduct::~IProduct() {}
//产品子类A
class IConcreteProductA : public IProduct
{
public:
~IConcreteProductA() {}
IConcreteProductA()
{
cout << "IConcreteProductA..." << endl;
}
};
//产品子类B
class IConcreteProductB : public IProduct
{
public:
~IConcreteProductB() {}
IConcreteProductB()
{
cout << "IConcreteProductB..." << endl;
}
};
//产品子类C
class IConcreteProductC : public IProduct
{
public:
~IConcreteProductC() {}
IConcreteProductC()
{
cout << "IConcreteProductC..." << endl;
}
};
//工厂类
class IConcreteFactory
{
public:
~IConcreteFactory() {}
IConcreteFactory()
{
cout << "IConcreteFactory..." << endl;
}
//工厂子类中提供了实例化产品子类的调用接口
//很好地将提前操作封装起来,实现代码的高内聚低耦合,提高了代码的可维护性和可扩展性
//可以通过参数switch不同的产品子类的实例化调用接口
IProduct* ICreateProduct(int num)
{
switch (num)
{
case 0:
return new IConcreteProductA();
break;
case 1:
return new IConcreteProductB();
break;
case 2:
return new IConcreteProductC();
break;
default:
break;
}
}
};
int main0()
{
IConcreteFactory * fac = new IConcreteFactory();//创建工厂类
//利用工厂类提供的调用接口实例化某一种产品对象
IProduct* pA = fac->ICreateProduct(0);
IProduct* pB = fac->ICreateProduct(1);
IProduct* pC = fac->ICreateProduct(2);
delete pA;
delete pB;
delete pC;
delete fac;
return 0;
}
/*工厂方法模型*/
//产品父类
class Product
{
public:
virtual ~Product() = 0;
protected:
Product() {};
};
Product::~Product() {}
//产品子类A
class ConcreteProductA : public Product
{
public:
~ConcreteProductA() {}
ConcreteProductA()
{
cout << "ConcreteProductA..." << endl;
}
};
//产品子类B
class ConcreteProductB : public Product
{
public:
~ConcreteProductB() {}
ConcreteProductB()
{
cout << "ConcreteProductB..." << endl;
}
};
//产品子类C
class ConcreteProductC : public Product
{
public:
~ConcreteProductC() {}
ConcreteProductC()
{
cout << "ConcreteProductC..." << endl;
}
};
//工厂父类
class Factory
{
public:
virtual ~Factory() = 0;
//工厂父类中提供实例化不同产品子类的调用接口,即纯虚函数
//在工厂子类中重写调用接口,多个调用接口的重载以实现实例化不同的产品子类
//这样就将实例化产品子类对象的操作延迟到了工厂子类中
virtual Product* CreateProduct(int num) = 0;
protected:
Factory() {}
};
Factory::~Factory() {}
//工厂子类
class ConcreteFactory : public Factory
{
public:
~ConcreteFactory() {}
ConcreteFactory()
{
cout << "ConcreteFactory..." << endl;
}
//工厂子类中提供了实例化产品子类的调用接口
//很好地将提前操作封装起来,实现代码的高内聚低耦合,提高了代码的可维护性和可扩展性
//可以通过参数switch不同的产品子类的实例化调用接口
Product* CreateProduct(int num)
{
switch (num)
{
case 0:
return new ConcreteProductA();
break;
case 1:
return new ConcreteProductB();
break;
case 2:
return new ConcreteProductC();
break;
default:
break;
}
}
};
int main1()
{
Factory* fac = new ConcreteFactory();//创建工厂子类
//利用工厂子类提供的调用接口实例化某一种产品对象
Product* pA = fac->CreateProduct(0);
Product* pB = fac->CreateProduct(1);
Product* pC = fac->CreateProduct(2);
delete pA;
delete pB;
delete pC;
delete fac;
return 0;
}
/*抽象工厂模型*/
//产品A父类
class AbstractProductA
{
public:
virtual ~AbstractProductA() {}
protected:
AbstractProductA() {}
};
//产品B父类
class AbstractProductB
{
public:
virtual ~AbstractProductB() {}
protected:
AbstractProductB() {}
};
//产品A的子类A1
class ProductA1 : public AbstractProductA
{
public:
ProductA1()
{
cout << "ProductA1..." << endl;
}
~ProductA1() {}
};
//产品A的子类A2
class ProductA2 : public AbstractProductA
{
public:
ProductA2()
{
cout << "ProductA2..." << endl;
}
~ProductA2() {}
};
//产品B的子类B1
class ProductB1 : public AbstractProductB
{
public:
ProductB1()
{
cout << "ProductB1..." << endl;
}
~ProductB1() {}
};
//产品B的子类B2
class ProductB2 : public AbstractProductB
{
public:
ProductB2()
{
cout << "ProductB2..." << endl;
}
~ProductB2() {}
};
//抽象工厂父类
class AbstractFactory
{
public:
virtual ~AbstractFactory() {}
//工厂中生产有可能生产多种类型的产品,所以对应不同的调用接口
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
protected:
AbstractFactory() {}
};
//抽象工厂子类CF1
class ConcreteFactory1 : public AbstractFactory
{
public:
ConcreteFactory1() {}
~ConcreteFactory1() {}
//工厂CF1针对A产品的初始化调用接口实现
AbstractProductA* CreateProductA()
{
return new ProductA1();
}
//工厂CF1针对B产品的初始化调用接口实现
AbstractProductB* CreateProductB()
{
return new ProductB1();
}
};
//抽象工厂子类CF2
class ConcreteFactory2 : public AbstractFactory
{
public:
ConcreteFactory2() {}
~ConcreteFactory2() {}
//工厂CF2针对A产品的初始化调用接口实现
AbstractProductA* CreateProductA()
{
return new ProductA2();
}
//工厂CF2针对B产品的初始化调用接口实现
AbstractProductB* CreateProductB()
{
return new ProductB2();
}
};
int main2()
{
AbstractFactory* cf1 = new ConcreteFactory1();//创建抽象工厂子类CF1
AbstractProductA* pA1 = cf1->CreateProductA();//在CF1中生产产品A的子类A1
AbstractProductB* pB1 = cf1->CreateProductB();//在CF1中生产产品B的子类B1
AbstractFactory* cf2 = new ConcreteFactory2();//创建抽象工厂子类CF2
AbstractProductA* pA2 = cf2->CreateProductA();//在CF2中生产产品A的子类A2
AbstractProductB* pB2 = cf2->CreateProductB();//在CF2中生产产品B的子类B2
delete cf1;
delete pA1;
delete pB1;
delete cf2;
delete pA2;
delete pB2;
return 0;
}