工厂模式
工厂模式在设计模式中属于创建型模式,他提供了一种创建对象的最佳方法。在工厂模式中,我们并不会暴露给用户任何创建对象的信息,而是通过一个共同的接口来创建对象。
工厂模式主要解决了接口选择的问题,其实更直白的说,您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
工厂模式大体的分为三类,分别为简单工厂模式、工厂方法模式和抽象工厂模式,下面来一起看看这三种模式是如何实现的。
简单工厂模式
如同他的名字一样,简单工厂模式是工厂模式中最简单的一种,他用最简单的方式来隐藏对象创建的细节。使用时你只需要知道你所想要的对象类型即可
下面实现的工厂模式方法可以根据你希望创建的对象类型进行创建不同的对象,并且可以通过同一个接口实现:
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
enum {
typeA,
typeB
};
class product {
public:
virtual void show() = 0;
};
class productA : public product{
public:
virtual void show()
{
cout << "product A" << endl;
}
};
class productB : public product{
public:
virtual void show()
{
cout << "product B" << endl;
}
};
class Factory{
public:
static product* CreateObject(int type)
{
switch (type)
{
case typeA:
return new productA();
case typeB:
return new productB();
default:
break;
}
}
};
int main()
{
Factory* fy = new Factory();
product* Fa = fy->CreateObject(typeA);
Fa->show();
product* Fb = fy->CreateObject(typeB);
Fb->show();
system("pause");
return 0;
}
可以看出,简单工厂模式只是在工厂类中进行类型判断,从而new一个相应的对象返回罢了。但是简单工厂模式其实是存在一定的问题的,设计模式的六大原则中有一大原则就是开闭原则,意思是说我们设计的类可以进行拓展但是尽量不要去修改。
很明显如果我们此时加入了C类对象我们就需要对工厂方法进行代码的修改,而且每次加入都会影响代码。所以简单工厂模式适用于产品子类不多的场合。
为了解决这个问题,我们紧接着来看第二种工厂方法模式。
工厂方法模式
简单工厂模式由于违背了开闭原则,所以意味着我们不可能使用一个相同的工厂来创建不同的类。所以工厂方法模式将工厂抽象了出来,而具体什么工厂创建什么对象由他的子类去完成,代码如下。
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
class product {
public:
virtual void show() = 0;
};
class productA : public product{
public:
virtual void show()
{
cout << "product A" << endl;
}
};
class productB : public product{
public:
virtual void show()
{
cout << "product B" << endl;
}
};
class Factory{
public:
virtual product* CreateObject() = 0;
};
class FactoryA : public Factory{
public:
virtual product* CreateObject()
{
return new productA();
}
};
class FactoryB : public Factory{
public:
virtual product* CreateObject()
{
return new productB();
}
};
int main()
{
Factory* fya = new FactoryA();
product* Fa = fya->CreateObject();
Fa->show();
Factory* fyb = new FactoryB();
product* Fb = fyb->CreateObject();
Fb->show();
system("pause");
return 0;
}
相对于简单工厂模式来说,工厂方法模式遵循了开闭原则,并且将工厂抽象出来。如果希望创建出其他类型的对象,就添加新的工厂子类。
抽象工厂模式
上面说工厂方法模式不是说完美的解决了开闭问题么,那为什么还会有抽象工厂模式呢?其实我们可以发现,上面的两种模式只适合产品种类单一的商品。
就是说我们如果生产烟,只能生产好猫牌的香烟。可是我的工厂可能还能生产好狗牌的香烟,那么我们如何让一个工厂同时既能生产好猫牌香烟,又能生产好狗牌香烟呢?
此时我们就要使用抽象工厂模式,在抽象出作为基类的工厂类中提供不同类的创建纯虚函数,然后在工厂子类中重写这些虚函数。
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
class dog {
public:
virtual void show() = 0;
};
class dogA : public dog{
public:
virtual void show()
{
cout << "dog A" << endl;
}
};
class dogB : public dog{
public:
virtual void show()
{
cout << "dog B" << endl;
}
};
class cat {
public:
virtual void show() = 0;
};
class catA : public cat{
public:
virtual void show()
{
cout << "cat A" << endl;
}
};
class catB : public cat{
public:
virtual void show()
{
cout << "cat B" << endl;
}
};
class Factory{
public:
virtual dog* CreateDog() = 0;
virtual cat* CreateCat() = 0;
};
class FactoryA : public Factory{
public:
virtual dog* CreateDog()
{
return new dogA();
}
virtual cat* CreateCat()
{
return new catA();
}
};
class FactoryB : public Factory{
public:
virtual dog* CreateDog()
{
return new dogB();
}
virtual cat* CreateCat()
{
return new catB();
}
};
int main()
{
Factory* fya = new FactoryA();
dog* da = fya->CreateDog();
da->show();
cat* ca = fya->CreateCat();
ca->show();
cout << endl;
Factory* fyb = new FactoryB();
dog* db = fyb->CreateDog();
db->show();
cat* cb = fyb->CreateCat();
cb->show();
system("pause");
return 0;
}
抽象工厂模式封装了对象的创建,只要我们知道工厂就可以创建出一组对象。但是缺点也很明显,比如新增一个对象,要在每个工厂中再添加一种方法,违反了开闭原则。
工厂模式的优缺点
其实不管是三种工厂模式的哪种模式,都具备以下的优点:
- 一个调用者想创建一个对象,只要知道其名称就可以了
- 屏蔽产品的具体实现,调用者只关心产品的接口
他们除了工厂方法模式,其他两种模式其实也存在一定的缺点:
- 每次增加一类对象或者增加一组新对象,就要违反开闭原则修改代码
- 如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度