工厂模式
工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。(生成对象,屏蔽对象生成的细节)
用一个单独的类来做创造实例的过程,就是工厂。
1.简单工厂模式
定义与特点
简单工厂模式是属于创建者模式,又叫做静态工厂方法模式,是工厂模式中最简单的一种,可以理解为是不同工厂模式的一个特殊实现。它可以用比较简单的方式隐藏创建对象的细节,是由一个工厂对象决定创建出哪种产品类的实例。
缺点:对修改不封闭,新增加产品就需要修改工厂。违反了开放封闭法则(OCP)。
结构与实现
-
工厂角色:简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品的方法可以被外界直接调用,创建所需的产品对象。
-
抽象产品角色:简单工厂模式创建的所有对象的父类,负责描述所有实例所共有的接口。
-
具体产品角色:是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
class Fruit
{
public:
Fruit(string name):mname(name){}
virtual void option()=0;
protected:
string mname;
};
class Apple:public Fruit
{
public:
Apple(string name):Fruit(name){}
void option()
{
cout<<"this is an "<<mname<<endl;
}
};
class Pear:public Fruit
{
public:
Pear(string name):Fruit(name){}
void option()
{
cout<<"this is a "<<mname<<endl;
}
};
class Banana:public Fruit
{
public:
Banana(string name):Fruit(name){}
void option()
{
cout<<"this is a "<<mname<<endl;
}
};
class Factory
{
public:
Factory(){}
Fruit* CreateProduct(int flag)
{
switch(flag)
{
case 1:
return new Apple("apple");
break;
case 2:
return new Pear("Pear");
break;
case 3:
return new Banana("Banana");
break;
default:
cout<<"no this product!"<<endl;
break;
}
}
};
int main()
{
Factory f;
Fruit *pf=f.CreateProduct(3);
pf->option();
}
- 我们发现如果要需要其他产品,就不得不去修改工厂的代码,就会违反开放封闭原则。
2.工厂方法模式
定义与特点
在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
结构与实现
- 抽象工厂角色:是工厂方法模式的核心
- 具体工厂角色:实现抽象工厂的具体工厂类,受到应用程序调用以创建产品对象
- 抽象产品角色:工厂方法模式创建的对象类型,即产品对象的共同父类。
- 具体产品角色:实现了抽象产品角色对应的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应
class Fruit
{
public:
Fruit(string name):mname(name){}
virtual void option()=0;
protected:
string mname;
};
class Apple:public Fruit
{
public:
Apple(string name):Fruit(name){}
void option()
{
cout<<"this is an "<<mname<<endl;
}
};
class Pear:public Fruit
{
public:
Pear(string name):Fruit(name){}
void option()
{
cout<<"this is a "<<mname<<endl;
}
};
class Factory
{
public:
Factory(string name):mname(name)
{}
virtual Fruit* createProduct()=0;
protected:
string mname;
};
class F1:public Factory
{
public:
F1(string name):Factory(name)
{}
Fruit* createProduct()
{
return new Apple("apple");
}
};
class F2:public Factory
{
public:
F2(string name):Factory(name)
{}
Fruit* createProduct()
{
return new Pear("Pear");
}
};
int main()
{
Factory* pf=new F2("f2");
Fruit* pff=pf->createProduct();
pff->option();
}
那么如果需要创建一个其他的产品呢?
class Banana:public Fruit
{
public:
Banana(string name):Fruit(name){}
void option()
{
cout<<"this is a "<<mname<<endl;
}
};
class F3:public Factory
{
public:
F3(string name):Factory(name)
{}
Fruit* createProduct()
{
return new Banana("Banana");
}
};
- 这时我们发现如果需要一个其他的产品对象,我们就不需要修改产品类的代码,只需要添加一个工厂类以及工厂对应的产品类就可以创建出对应的产品对象。就不会违背开放封闭原则。
3.抽象方法模式
定义与特点
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级(种类) 的产品。
加粗样式
使用抽象工厂模式一般要满足以下条件。
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当增加一个新的产品族时不需要修改原代码,满足开闭原则。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
结构与实现
-
抽象工厂:提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
-
具体工厂:主要是实现抽象工厂中的多个抽象方法,完整具体产品的创建。
-
抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
-
具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
class A
{
public:
A(string name):mname(name){}
virtual void option()=0;
protected:
string mname;
};
class A1:public A
{
public:
A1(string name):A(name){}
void option()
{
cout<<"A1"<<endl;
}
};
class A2:public A
{
public:
A2(string name):A(name){}
void option()
{
cout<<"A2"<<endl;
}
};
class B
{
public:
B(string name):mname(name){}
virtual void option()=0;
protected:
string mname;
};
class B1:public B
{
public:
B1(string name):B(name){}
void option()
{
cout<<"B1"<<endl;
}
};
class B2:public B
{
public:
B2(string name):B(name){}
void option()
{
cout<<"B2"<<endl;
}
};
class AbstractFactory
{
public:
AbstractFactory(string name):mname(name)
{}
virtual A* createProductA()=0;
virtual B* createProductB()=0;
protected:
string mname;
};
class ABF1:public virtual AbstractFactory
{
public:
ABF1(string name):AbstractFactory(name){}
A* createProductA()
{
return new A1("A1");
}
B* createProductB()
{
return new B1("B1");
}
};
class ABF2:public virtual AbstractFactory
{
public:
ABF2(string name):AbstractFactory(name){}
A* createProductA()
{
return new A2("A2");
}
B* createProductB()
{
return new B2("B2");
}
};
int main()
{
AbstractFactory* paf=new ABF1("ABF1");
A* pa=paf->createProductA();
B* pb=paf->createProductB();
pa->option();
pb->option();
return 0;
}