一、简单工厂模式
/*基类,鞋子*/
class Shoes
{
public:
virtual void show() = 0;
virtual ~Shoes() {}
};
//耐克鞋子
class NikeShoes : public Shoes
{
public:
void show() {cout << "我是耐克鞋子" << endl;}
};
//安踏鞋子
class AntaShoes : public Shoes
{
public:
void show(){cout << "我是安踏鞋子" << endl;}
};
enum SHOES_TYPE {NIKE, ANTA};
/*简单工厂*/
class Factory {
Shoes *CreateShoes(SHOES_TYPE type)
{
switch(type)
{
case NIKE:
return new NikeShoes;
break;
case ANTA:
return new AntaShoes;
break;
defult:
return nullptr;
}
}
};
int main()
{
Factory* nike_shoes = new Factory;
nike_shoes->CreateShoes(NIKE)->show();//我是耐克鞋子
Factory* anta_shoes = new AntaShoes;
anta_shoes->CreateShoes(ANTA)->show();//我是安踏鞋子
}
二、工厂方法模式
/*总鞋厂*/
class Factory
{
public:
virtual Shoes* createShoes() = 0;
virtual ~Factory() {}
};
/*生产耐克鞋子的鞋厂*/
class NikeProducer :public Factory
{
public:
Shoes* createShoes()
{
return new NikeShoes();
}
virtual ~NikeProducer() {}
};
/*生产安踏鞋子的鞋厂*/
class AntaProducer :public Factory
{
public:
Shoes* createShoes()
{
return new AntaShoes();
}
virtual ~AntaProducer() {}
};
//耐克鞋子
class NikeShoes : public Shoes
{
public:
void show() { cout << "我是耐克鞋子" << endl; }
};
//安踏鞋子
class AntaShoes : public Shoes
{
public:
void show() { cout << "我是安踏鞋子" << endl; }
};
int main()
{
Factory* nike_shoes = new NikeProducer;
nike_shoes->createShoes()->show();//我是耐克鞋子
Factory* anta_shoes = new AntaProducer;
anta_shoes->createShoes()->show();//我是安踏鞋子
}
三、抽象工厂模式
抽象工厂和工厂方法模式一样,只不过生产的产品种类增多,仍借用上面的例子,原来只生产鞋子现在增加衣服一类产品,代码如下:
/*总厂,既生产鞋子,也生产衣服*/
class Factory
{
public:
virtual Shoes* createShoes() = 0;
virtual Clothes* createClothes() = 0;
virtual ~Factory() {}
};
/*生产耐克鞋子/衣服*/
class NikeProducer :public Factory
{
public:
Shoes* createShoes()
{
return new NikeShoes();
}
Clothes* createClothes()
{
return new NikeClothes();
}
virtual ~NikeProducer() {}
};
/*生产安踏鞋子/衣服*/
class AntaProducer :public Factory
{
public:
Shoes* createShoes()
{
return new AntaShoes();
}
Clothes* createClothes()
{
return new AntaClothes();
}
virtual ~AntaProducer() {}
};
int main()
{
Factory* nike_shoes = new NikeProducer;
nike_shoes->createShoes()->show();//我是耐克鞋子
Factory* nike_clothes = new NikeProducer;
nike_clothes->createShoes()->show();//我是耐克衣服
Factory* anta_shoes = new AntaProducer;
anta_shoes->createClothes()->show();//我是安踏鞋子
Factory* anta_clothes = new AntaProducer;
anta_clothes->createClothes()->show();//我是安踏衣服
}
上述三种工厂模式都有一个缺点,当需要增加一个产品时,如李宁鞋子,优衣库衣服... ...则需要增加一个:产品工厂类 class NikeProducer :public Factory
为了提高产品的封装性,下面提出了抽象模板工厂类。
四、抽象模板工厂类
/*基类,鞋子*/
class Shoes
{
public:
virtual void show() = 0;
virtual ~Shoes() {}
};
//耐克鞋子
class NikeShoes : public Shoes
{
public:
void show() {cout << "我是耐克鞋子" << endl;}
};
//安踏鞋子
class AntaShoes : public Shoes
{
public:
void show(){cout << "我是安踏鞋子" << endl;}
};
/*基类,衣服*/
class Clothes
{
public:
virtual void show() = 0;
virtual ~Clothes() {}
};
//耐克衣服
class NikeClothes : public Clothes
{
public:
void show(){cout << "我是耐克衣服" << endl;}
};
//安踏衣服
class AntaClothes : public Clothes
{
public:
void show(){cout << "我是安踏衣服" << endl;}
};
/*抽象模板工厂类*/
template<class productType, class producerType>
class Factory {
public:
//productType: Shoes 、 Clothes
//producerType:Shoes{NikeShoes,AntaShoes} 、 Clothes{NikeClothes,AntaClothes}
//该模板函数会构造对应的生产线对象:耐克鞋子生产线、安踏鞋子生产线、耐克衣服生产线、安踏衣服生产线
//并返回对应产品的的类对象:鞋子、衣服。但是由于多态的特点,实际返回对象在show时会根据实际生产线来决定
productType* createProduct()
{
return new producerType();
}
};
int main()
{
Factory<Shoes, NikeShoes>* nike_shoes = new Factory<Shoes, NikeShoes>;
nike_shoes->createProduct()->show();//我是耐克鞋子
Factory<Shoes, AntaShoes>* anta_shoes = new Factory<Shoes, AntaShoes>;
anta_shoes->createProduct()->show();//我是安踏鞋子
Factory<Clothes, NikeClothes>* nike_clothes = new Factory<Clothes, NikeClothes>;
nike_clothes->createProduct()->show();//我是耐克衣服
Factory<Clothes, AntaClothes>* anta_clothes = new Factory<Clothes, AntaClothes>;
anta_clothes->createProduct()->show();//我是安踏衣服
}
采用模板工厂类的方式,当需要再次添加一个品牌产品时,只需要定义一个描述新产品的类即可,例如:
//李宁鞋子
class LiningShoes : public Shoes
{
public:
void show(){cout << "我是李宁鞋子" << endl;}
};
//耐克衣服
class LiningClothes : public Clothes
{
public:
void show(){cout << "我是李宁衣服" << endl;}
};
Factory<Shoes, LiningShoes>* lining_shoes = new Factory<Clothes, LiningShoes>;
lining_shoes->createProduct()->show();//我是李宁鞋子
Factory<Shoes, LiningClothes>* anta_shoes = new Factory<Clothes, LiningClothes>;
lining_clothes->createProduct()->show();//我是李宁衣服