简单工厂模式、工厂方法模式、抽象工厂模式
一.简单工厂模式
1.概念
不想创建对象,只想使用这个对象,所以将创建对象的任务交给工厂来实现
注意:简单工厂模式不属于23种设计模式
2.优缺点
优点:
客户端和具体实现类分离,不用考虑创建某些复杂对象的情况
缺点:
增加新功能是通过修改源代码实现,不符合开闭原则
工厂类职责过重,工厂类出现问题,会影响很多使用这个工厂的模块
3.适用场景:
1)工厂类负责创建的对象比较少,由于创建的对象比较少,
不会造成工厂方法中的业务逻辑太过复杂;
2)客户端只知道传入工厂类的参数,对于如何创建并不关心;
4.代码示例
#include<iostream>
#include<string>
using namespace std;
//抽象水果类
class AbstractFruit{
public:
virtual void showName() = 0;
};
class Apple :public AbstractFruit{
public:
virtual void showName()
{
cout << "我是一个苹果" << endl;
}
};
class Banana :public AbstractFruit{
public:
virtual void showName()
{
cout << "我是一个香蕉" << endl;
}
};
class Orange :public AbstractFruit{
public:
virtual void showName()
{
cout << "我是一个橘子" << endl;
}
};
class Peach :public AbstractFruit{
public:
virtual void showName()
{
cout << "我是一个桃子" << endl;
}
};
//水果工厂
class FruitFactory{
public:
AbstractFruit* FruitCreate(string name)
{
if (name == "apple")
{
return new Apple;
}
else if (name == "banana")
{
return new Banana;
}
else if (name == "orange")
{
return new Orange;
}
else if (name == "peach")
{
return new Peach;
}
else
{
return NULL;
}
}
};
//客户端不和具体的类交互,而是和工厂类进行交互
void test()
{
//创建过程不需要关心,直接拿来用
FruitFactory* factory=new FruitFactory;
AbstractFruit* fruit = factory->FruitCreate("apple");
fruit->showName();
delete fruit;
fruit = NULL;
fruit = factory->FruitCreate("banana");
fruit->showName();
delete fruit;
fruit = NULL;
fruit = factory->FruitCreate("orange");
fruit->showName();
delete fruit;
fruit = NULL;
fruit = factory->FruitCreate("peach");
fruit->showName();
delete fruit;
fruit = NULL;
delete factory;
factory = NULL;
}
int main()
{
test();
return 0;
}
二.工厂方法模式
1.概念
定义一个抽象工厂类,再让其他类继承这个抽象工厂类,并重写抽象工厂类的方法,每次生成一个产品,就需要创建一个具体的工厂类
2.优缺点
优点:
1)新增产品时,只需要增加具体的工厂类和具体的产品类,不需要修改原工厂,符合开闭原则;
2)用户只要知道具体工厂的名称就可以得到产品,不需要关心产品的创建过程;
缺点:
1) 每当要增加一个新的产品时,就要增加一个新的工厂类和产品类,类的个数成倍增加,导致类越来越多,增加了维护成本;
2) 需要客户自己判断调用那个工厂来创建类对象;
3.适用场景
1)客户端不知道它所需对象的类;
2)抽象工厂类通过其子类来指定创建哪个对象;
4.代码示例
#include<iostream>
#include<string>
using namespace std;
//工厂方法模式
//抽象水果类
class AbstractFruit{
public:
virtual void showName() = 0;
};
//具体水果类
//苹果类
class Apple :public AbstractFruit{
public:
virtual void showName()
{
cout << "I am apple" << endl;
}
};
//橘子类
class Orange : public AbstractFruit{
public:
virtual void showName()
{
cout << "I am orange" << endl;
}
};
//抽象工厂类
class AbstractFactory{
public:
virtual AbstractFruit* FruitCreate() = 0;
};
//具体工厂类
//苹果工厂
class Factory_apple:public AbstractFactory{
public:
virtual AbstractFruit* FruitCreate()
{
return new Apple;
}
};
//橘子工厂
class Factory_orange :public AbstractFactory{
public:
virtual AbstractFruit* FruitCreate()
{
return new Orange;
}
};
//客户端通过抽象工厂来调用具体工厂
void test()
{
AbstractFactory* factory =NULL;
AbstractFruit* fruit = NULL;
//创建苹果工厂
factory = new Factory_apple;
fruit = factory->FruitCreate();
fruit->showName();
delete fruit;
fruit = NULL;
delete factory;
factory = NULL;
//创建橘子工厂
factory = new Factory_orange;
fruit = factory->FruitCreate();
fruit->showName();
delete fruit;
fruit = NULL;
delete factory;
factory = NULL;
}
int main()
{
test();
return 0;
}
三.抽象工厂模式
0.相关概念
产品等级
产品等级指的是同一种级别的产品
如小米电脑、华为电脑、惠普电脑都属于电脑这个产品等级
产品族
在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品
如小米公司生产的手机、电脑、智能音响都属于小米公司这个产品族
1.概念
一种生产同一产品族的设计模式,超级工厂生产抽象产品,具体工厂继承超级工厂并生产自己对应产品族的产品。
抽象工厂模式是工厂方法模式的升级版,工厂方法模式只能生产同一级别的产品,如菠萝工厂只能生产菠萝;而抽象工厂模式可以生产同一产品族的一系列产品,如华为公司可以生产电脑、pad、手机
抽象工厂模式针对产品族,而不是针对产品等级
2.优缺点
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:扩展产品族需要修改所有的工厂类,不符合开闭原则
3.适用场景
1)当需要创建的产品属于同一个产品族;
2)系统中有多个产品族,每次只使用其中的某一族;
3)客户端不关心产品的创建过程,只是使用该产品;
4.代码实例
#include <iostream>
using namespace std;
//抽象工厂模式
//斗王
class DouWang{
public:
virtual void showTime() = 0;
};
//斗皇
class DouHuang {
public:
virtual void showTime() = 0;
};
//斗宗
class DouZong {
public:
virtual void showTime() = 0;
};
//古族斗王
class GuZuDouWang : public DouWang
{
public:
virtual void showTime()
{
cout << "古族斗王0号" << endl;
}
};
//魂族斗王
class HunZuDouWang : public DouWang
{
public:
virtual void showTime()
{
cout << "魂族斗王3号" << endl;
}
};
//太虚古龙族斗王
class TaiXuGuLongZuDouWang : public DouWang
{
public:
virtual void showTime()
{
cout << "太虚古龙族斗王1号" << endl;
}
};
//古族斗皇
class GuZuDouHuang : public DouHuang
{
public:
virtual void showTime()
{
cout << "古族斗皇66号" << endl;
}
};
//魂族斗皇
class HunZuDouHuang : public DouHuang
{
public:
virtual void showTime()
{
cout << "魂族斗皇4号" << endl;
}
};
//太虚古龙族斗皇
class TaiXuGuLongZuDouHuang : public DouHuang
{
public:
virtual void showTime()
{
cout << "太虚古龙族斗皇0号" << endl;
}
};
//古族斗宗
class GuZuDouZong : public DouZong
{
public:
virtual void showTime()
{
cout << "古族斗宗1号" << endl;
}
};
//魂族斗宗
class HunZuDouZong : public DouZong
{
public:
virtual void showTime()
{
cout << "魂族斗宗3号" << endl;
}
};
//太虚古龙族斗宗
class TaiXuGuLongZuDouZong : public DouZong
{
public:
virtual void showTime()
{
cout << "太虚古龙族斗宗007号" << endl;
}
};
//超级工厂
class SuperFactory {
public:
//生产斗王
virtual DouWang* createDouWang() = 0;
//生产斗皇
virtual DouHuang* createDouHuang() = 0;
//生产斗宗
virtual DouZong* createDouZong() = 0;
};
//古族工厂
class GuZuFactory : public SuperFactory{
public:
virtual DouWang* createDouWang()
{
return new GuZuDouWang;
}
virtual DouHuang* createDouHuang()
{
return new GuZuDouHuang;
}
virtual DouZong* createDouZong()
{
return new GuZuDouZong;
}
};
//魂族工厂
class HunZuFactory : public SuperFactory
{
public:
virtual DouWang* createDouWang()
{
return new HunZuDouWang;
}
virtual DouHuang* createDouHuang()
{
return new HunZuDouHuang;
}
virtual DouZong* createDouZong()
{
return new HunZuDouZong;
}
};
//太虚古龙族工厂
class TaiXuGuLongZuFactory : public SuperFactory
{
public:
virtual DouWang* createDouWang()
{
return new TaiXuGuLongZuDouWang;
}
virtual DouHuang* createDouHuang()
{
return new TaiXuGuLongZuDouHuang;
}
virtual DouZong* createDouZong()
{
return new TaiXuGuLongZuDouZong;
}
};
void client()
{
//生产古族强者
SuperFactory* factory = new GuZuFactory;
DouWang* person1 = factory->createDouWang();
DouHuang* person2 = factory->createDouHuang();
DouZong* person3 = factory->createDouZong();
person1->showTime();
person2->showTime();
person3->showTime();
delete person1;
delete person2;
delete person3;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
//生产魂族强者
factory = new HunZuFactory;
person1 = factory->createDouWang();
person2 = factory->createDouHuang();
person3 = factory->createDouZong();
person1->showTime();
person2->showTime();
person3->showTime();
delete person1;
delete person2;
delete person3;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
//生产太虚古龙族强者
factory = new TaiXuGuLongZuFactory;
person1 = factory->createDouWang();
person2 = factory->createDouHuang();
person3 = factory->createDouZong();
person1->showTime();
person2->showTime();
person3->showTime();
delete person1;
delete person2;
delete person3;
}
int main()
{
client();
return 0;
}
四.抽象工厂模式和工厂方法模式的区别
1.抽象工厂模式针对多个产品等级结构,而工厂方法模式针对的是单个产品等级结构;
2.抽象工厂模式生产多个抽象产品类,而工厂方法模式生产单个抽象产品类;
3.抽象工厂模式的每个具体工厂可以生产多种具体产品,而工厂方法模式的具体工厂只能生产一种具体产品。