设计模式
简单工厂模式
不用工厂模式的生成对象的弊端的例子——构造函数最好不要写业务,我们的业务实现太依赖于构造函数了
class Fruit{
public:
Fryit(string kind){
if(this->kind=="apple"){}
else if(this->kind=="banana"){}
}
void getName(){
if(this->kind=="apple")
cout<<"I AM APPLE"<<endl;
else if(this->kind=="banana")
cout<<"I AM BANANA"<<endl;
}
};
int main(){
Fruit apple("apple");
apple.getName();
Fruit banana("banana");
banana.getName();
}
工厂模式的目的就是让业务层和类的构造函数解耦合,尽可能降低一个类的函数复杂度
简单工厂模式怎么做呢?
简单工厂模式例子如下:
class Fruit{
public:
void getName()=0;
};
class Apple:public Fruit{
public:
virtual void getName(){
cout<<"apple"<<endl;
}
};
class Banana:public Fruit{
public:
virtual void getName(){
cout<<"Banana"<<endl;
}
};
//写一个工厂
class Factory{
public:
create(string kind){
if(kind=="apple") return new Apple;
else if(kind=="banana") return new Banana;
}
}
int main(){
Factory *factory=new Factory;
//要一个苹果
//抽象的指针指向具体的对象,发生多态
Fruit *apple=factory->create("apple");
apple->getName();
return 0;
}
但是随着水果种类的增加,工厂类中的方法也要进行修改,因此GoF不承认简单工厂模式是设计模式。
扫描二维码关注公众号,回复:
5519321 查看本文章
工厂模式
简单工厂模式+开闭原则=工厂模式
工厂模式实现代码:
class Fruit{
public:
void getName()=0;
};
class Apple:public Fruit{
public:
virtual void getName(){
cout<<"apple"<<endl;
}
};
class Banana:public Fruit{
public:
virtual void getName(){
cout<<"Banana"<<endl;
}
};
//抽象工厂
class AbstractFactory{
public:
//抽象的生产器
virtual Fruit* creatFruit()=0;
};
//具体工厂
class APPLEFactory: public AbstractFactory{
public:
//抽象的生产器
virtual Fruit* creatFruit(){
return new Apple;
}
};
class BANANAFactory: public AbstractFactory{
public:
//抽象的生产器
virtual Fruit* creatFruit(){
return new Banana;
}
};
int main(){
//来一个生产苹果的工厂
AbstractFactory *appleFactory = new APPLEFactory;
Fruit *apple =APPLEFactory->creatFruit();
apple->getName();
//来一个香蕉工厂
//基类指针在子类对象中进行移动是安全的
//抽象的指针指向具体的对象,符合多态
AbstractFactory *bananaFactory=new BANANAFactory;
Fruit *banana=BANANAFactory->creatFruit();
banana->getName();
return 0;
}
抽象的工厂模式
目的——尽可能的降低工厂的个数
优点——有工厂模式很方便,增加新产品族很方便
缺点——增加产品结构很麻烦,还有可能需要修改抽象层代码
概念:产品族和产品等级结构
对于普通工厂模式,下图的需求需要对应九种具体工厂类
- 如果来自同一个产地(厂商),但是他们的每个产品完成的功能接口不同,我们称他们是一个产品族——壹横行
- 如果一系列产品,他们所提供的接口相同,比如都是苹果,但是来自不同的产地(厂商),我们称他们是一个产品等级结构。——壹纵列
因此,抽象工厂可以按照产品族划分——可以通过中国这个接口获取中国的苹果、中国的香蕉和中国的鸭梨
也可以按照产品等级结构进行划分——但是这样并不能降低工厂类的数量,如果我想要中国的三个厂,就需要分别制造三个类,而上面的方式只知道一个类,这种方式没有做到优化,因此这种方式不合适
实现创建中国和美国产品族,每个产品族中有苹果和香蕉产品等级结构
#include<iostream>
using namespace std;
class Fruit{
public:
virtual void getName=0;
};
//下面两个类是一个产品族
class ChinaApple:public Fruit{
public:
virtual void getName(){
cout<<"chinaApple"<<endl;
}
};
class ChinaBanana:public Fruit{
public:
virtual void getName(){
cout<<"ChinaBanana"<<endl;
}
};
//下面两个类是一个产品族
class USAApple:public Fruit{
public:
virtual void getName(){
cout<<"USAApple"<<endl;
}
};
class USABanana:public Fruit{
public:
virtual void getName(){
cout<<"USABanana"<<endl;
}
}
//抽象的工厂(根据产品族进行生产)
class AbstractFactory{
public:
//苹果的生产器
virtual Fruit*createApple()=0;
//香蕉的生产器
virtual Fruit*createBanana()=0;
};
//中国的工厂(虚函数都要实现,哪怕你不用)
class ChinaFactory:public AbstractFactory{
public:
//苹果的生产器
virtual Fruit* createApple(){
return new ChinaApple;
}
//香蕉的生产器
virtual Fruit* createBanana(){
return new ChinaBanana;
}
};
//美国的工厂
class USAFactory:public AbstractFactory{
public:
//苹果的生产器
virtual Fruit* createApple(){
return new USAApple;
}
//香蕉的生产器
virtual Fruit* createBanana(){
return new USABanana;
}
};
int main(){
//中国的系列产品
//利用一个对象生成统一产品族的商品
AbstractFactory *chinaFactory= new ChinaFactory;
Fruit *c_apple=chinaFactory->createApple();
Fruit *c_banana=chinaFactory->createBanana();
//要一个混合的产品,中国的苹果和美国的香蕉
//跨产品族的,创建的工厂类就和普通工厂类相同
AbstractFactory *useFactory= new USAFactory;
Fruit *u_banana=USAFactory->createBanana();
return 0;
}
总结:
工厂模式的目的——将对象的创建和使用相隔离。
例如游戏中,可以通过工厂创建花、创建龙。
- 简单的工厂模式对于工厂模式来讲,不符合开闭原则,简单工厂模式适用于产品个数极少的情况
- 工厂模式——工厂数量和产品数量一样多——适用于产品数量相对一般的情况
- 抽象的工厂模式——目的是在一定的条件下,减少工厂的个数