工厂模式分为3种,即简单工厂模式、工厂方法模式、抽象工厂模式。
一、简单工厂模式
简单工厂模式有一个工厂类,一个产品类。工厂类包含一个方法,可以选择生产某种类型的产品。产品基类是定义了接口,须要具体的产品去实现。
#include <iostream>
using namespace std;
// 定义产品接口类,食物,食物能吃
class Food {
public:
virtual void eat()=0;
};
// 定义具体产品,实现接口,水果能吃
class Fruit : public Food {
public:
virtual void eat() {
cout << "eat a fruit.\n";
}
};
// 蔬菜能吃
class Vegetable : public Food {
public:
virtual void eat() {
cout << "eat a vegetable.\n";
}
};
// 定义工厂类,可以创建不同类型的产品。
class FoodFactory {
public:
Food* CreateFood(int type) {
switch(type) {
case 1:
return new Fruit;
break;
case 2:
return new Vegetable;
break;
default:
return nullptr;
break;
}
}
};
int main()
{
FoodFactory * foodFactory = new FoodFactory;
Food* fruit = foodFactory->CreateFood(1);
Food* vegetable = foodFactory->CreateFood(2);
fruit->eat();
vegetable->eat();
return 0;
}
优点:封装复杂的创建逻辑,调用者无需了解如何创建对象,让原本的函数或类职责更单一,代码更简洁。
缺点:当需要新增产品时,需要新增一个产品类,并修改工厂类的代码。
二、工厂方法模式
由于简单工厂模式的弊端,发展出了工厂方法模式。工厂方法模式定义了一个接口(创建产品),可以有多个工厂实现这个接口,但是每个工厂只对应一个产品。此时工厂类和产品类都有基类,并且都包含接口。
#include <iostream>
using namespace std;
class Food {
public:
virtual void eat()=0;
};
class Fruit : public Food {
public:
virtual void eat() {
cout << "eat a fruit.\n";
}
};
class Vegetable : public Food {
public:
virtual void eat() {
cout << "eat a vegetable.\n";
}
};
// 定义工厂接口(创建产品)
class Factory {
public:
virtual Food* CreateFood()=0;
};
// 水果工厂实现接口,创建水果。一个工厂只能创建一种产品。
class FruitFactory : public Factory {
public:
virtual Food* CreateFood() {
return new Fruit;
}
};
// 蔬菜工厂创建蔬菜
class VegetableFactory : public Factory {
public:
virtual Food* CreateFood() {
return new Vegetable;
}
};
int main()
{
Factory *fruitFactory = new FruitFactory;
Factory *vegetableFactory = new VegetableFactory;
Food *fruit = fruitFactory->CreateFood();
Food* vegetable = vegetableFactory->CreateFood();
fruit->eat();
vegetable->eat();
return 0;
}
优点:增加新工厂属于扩展,不会修改以前工厂类和产品类的任何代码。
缺点:一个工厂类无法创建多种的产品。
三、抽象工厂模式
在工厂方法模式的基础上,如果一个工厂想要生产多个产品,就有了抽象工厂模式。我们可以让一个工厂负责创建多个不同类型的对象,这样就可以有效地减少工厂类的个数。
#include <iostream>
using namespace std;
// 产品一:食物
class Food {
public:
virtual void eat()=0;
};
// 水果属于食物
class Fruit : public Food {
public:
virtual void eat() {
cout << "eat a fruit.\n";
}
};
// 蔬菜属于食物
class Vegetable : public Food {
public:
virtual void eat() {
cout << "eat a vegetable.\n";
}
};
// 饮料
class Drink {
public:
virtual void drink() = 0;
};
// 西瓜汁
class XiGuaZhi : public Drink {
public:
virtual void drink() {
cout << "drink xiguazhi.\n";
}
};
// 玉米汁
class YuMiZhi : public Drink {
public:
virtual void drink() {
cout << "drink yumizhi.\n";
}
};
// 工厂接口:可以生产食物与饮料
class Factory {
public:
virtual Food* CreateFood()=0;
virtual Drink* CreateDrink()=0;
};
// 水果工厂,可以生产水果、西瓜汁
class FruitFactory : public Factory {
public:
virtual Food* CreateFood() {
return new Fruit;
}
virtual Drink* CreateDrink() {
return new XiGuaZhi;
}
};
// 蔬菜工厂,可以生产蔬菜、玉米汁
class VegetableFactory : public Factory {
public:
virtual Food* CreateFood() {
return new Vegetable;
}
virtual Drink* CreateDrink() {
return new YuMiZhi;
}
};
int main()
{
Factory *fruitFactory = new FruitFactory;
Factory *vegetableFactory = new VegetableFactory;
Food *fruit = fruitFactory->CreateFood();
Food *vegetable = vegetableFactory->CreateFood();
Drink *xiGuaZhi = fruitFactory->CreateDrink();
Drink *yuMiZhi = vegetableFactory->CreateDrink();
fruit->eat();
vegetable->eat();
xiGuaZhi->drink();
yuMiZhi->drink();
return 0;
}
优点:一个工厂可以生产多个产品
缺点:应用场景少