1.简单工厂
首先从简单工厂开始吧,简单工厂不是一个设计模式,反而比较像一种编程习惯,使用非常频繁。
应用分析
对象有一系列接口,但对象的创建可能是需要经常变化的地方,而对象的创建与实际的具体类型相关紧密,因此,我们将对象的创建封装在工厂类中,由它专门负责对象的创建,而且创建对象的方法可以声明为工厂类的静态方法,这样我们在使用对象的过程中,可以根据接口编程,分离了变化部分与不变部分,便于维护。
实例分析——Pizza店做好不同口味的Pizza,进行出售,Pizza的准备,烘烤,切块,打包流程一样,不同的Pizza需要不同的加工方案,而且Pizza的种类经常扩展,这样我们将不同Pizza加工分离出来,由Pizza工厂完成,Pizza店只是根据客户需求按不变的流程提供满足客户口味的Pizza。
代码分析
//Pizza.h
//具体Pizza类
#ifndef PIZZA_H
#define PIZZA_H
#include <iostream>
//Pizza接口
class Pizza
{
public:
virtual void prepare() = 0;
virtual void bake() = 0;
virtual void cut() = 0;
virtual void box() = 0;
};
//三个具体的pizza类
class CheesePizza:public Pizza
{
public:
void prepare()
{
std::cout<<"CheesePizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"CheesePizza bake"<<std::endl;
}
void cut()
{
std::cout<<"CheesePizza cut"<<std::endl;
}
void box()
{
std::cout<<"CheesePizza box"<<std::endl;
}
};
class ClamPizza:public Pizza
{
public:
void prepare()
{
std::cout<<"ClamPizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"ClamPizza bake"<<std::endl;
}
void cut()
{
std::cout<<"ClamPizza cut"<<std::endl;
}
void box()
{
std::cout<<"ClamPizza box"<<std::endl;
}
};
class VeggiePizza:public Pizza
{
public:
void prepare()
{
std::cout<<"VeggiePizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"VeggiePizza bake"<<std::endl;
}
void cut()
{
std::cout<<"VeggiePizza cut"<<std::endl;
}
void box()
{
std::cout<<"VeggiePizza box"<<std::endl;
}
};
#endif
//PizzaFactory.h
//Pizza工厂
#ifndef PIZZASTORE_H
#define PIZZASTORE_H
#include "Pizza.h"
class PizzaFactory//简单工厂
{
public:
static Pizza * createPizza(std::string type)
{
Pizza *PtrPizza=NULL;
if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
else if(!type.compare("Clam")) PtrPizza=new ClamPizza();
else if(!type.compare("Veggie")) PtrPizza=new VeggiePizza();
return PtrPizza;
}
};
#endif
//PizzaStore.h
//Pizza店
#ifndef PIZZAFACTORY_H
#define PIZZAFACTORY_H
#include "Pizza.h"
#include "PizzaFactory.h"
class PizzaStore
{
public:
Pizza * orderPizza(std::string type)//根据客户需求,按标准化流程提供Pizza
{
Pizza *res=PizzaFactory::createPizza(type);
if(!res) return res;
res->prepare();
res->bake();
res->cut();
res->box();
return res;
}
};
#endif
//Main.cpp
//测试程序
#include <iostream>
#include "PizzaStore.h"
int main()
{
PizzaStore *temStore=new PizzaStore();//创建Pizza店
temStore->orderPizza("Cheese");//根据客户需求生产Pizza
return 0;
}
2.工厂方法模式
定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
应用分析
所有的工厂模式都是用来封装对象的创建。工厂方法模式通过让子类决定创建的对象是什么,来达到对象创建过程的封装目的。这样,客户程序中关于超类的代码和子类对象创建代码解耦。
实例分析——同上,每个Pizza店可能加工Pizza的方法不同,需要有自己特有的Pizza加工方法,而由于Pizza处理过程一致,这样可以声明Pizza店的接口,而Pizza的生产过程,在具体Pizza店子类中,具体确定。
代码分析
//Pizza.h
//具体Pizza类
#ifndef PIZZA_H
#define PIZZA_H
#include <iostream>
//Pizza接口
class Pizza
{
public:
virtual void prepare() = 0;
virtual void bake() = 0;
virtual void cut() = 0;
virtual void box() = 0;
};
//三个具体的pizza类
class CheesePizza:public Pizza
{
public:
void prepare()
{
std::cout<<"CheesePizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"CheesePizza bake"<<std::endl;
}
void cut()
{
std::cout<<"CheesePizza cut"<<std::endl;
}
void box()
{
std::cout<<"CheesePizza box"<<std::endl;
}
};
class ClamPizza:public Pizza
{
public:
void prepare()
{
std::cout<<"ClamPizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"ClamPizza bake"<<std::endl;
}
void cut()
{
std::cout<<"ClamPizza cut"<<std::endl;
}
void box()
{
std::cout<<"ClamPizza box"<<std::endl;
}
};
class VeggiePizza:public Pizza
{
public:
void prepare()
{
std::cout<<"VeggiePizza prepare"<<std::endl;
}
void bake()
{
std::cout<<"VeggiePizza bake"<<std::endl;
}
void cut()
{
std::cout<<"VeggiePizza cut"<<std::endl;
}
void box()
{
std::cout<<"VeggiePizza box"<<std::endl;
}
};
#endif
//PizzaStore.h
//Pizza店
#ifndef PIZZAFACTORY_H
#define PIZZAFACTORY_H
#include "Pizza.h"
class PizzaStore
{
public:
Pizza * orderPizza(std::string type)//根据客户需求,按标准化流程提供Pizza
{
Pizza *res=CreatePizza(type);
if(!res) return res;
res->prepare();
res->bake();
res->cut();
res->box();
return res;
}
protected:
virtual Pizza * CreatePizza(std::string type)=0;//定义接口,由子类具体决定要实例化的类是哪一个
};
class NYPizzaStore:public PizzaStore//纽约Pizza店,生成纽约Pizza
{
protected:
Pizza * CreatePizza(std::string type)
{
Pizza *PtrPizza=NULL;
if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
else if(!type.compare("Clam")) PtrPizza=new ClamPizza();
return PtrPizza;;
}
};
class ChicagoPizzaStore:public PizzaStore//芝加哥Pizza店,生成芝加哥Pizza
{
protected:
Pizza * CreatePizza(std::string type)
{
Pizza *PtrPizza=NULL;
if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
else if(!type.compare("Veggie")) PtrPizza=new VeggiePizza();
return PtrPizza;
}
};
#endif
//Main.cpp
//测试程序
#include <iostream>
#include "PizzaStore.h"
int main()
{
PizzaStore *ps=new NYPizzaStore();
ps->orderPizza("Clam");
delete ps;
ps=NULL;
ps=new ChicagoPizzaStore();
ps->orderPizza("Veggie");
delete ps;
ps=NULL;
return 0;
}
3.抽象工厂模式
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指明具体类。
应用分析
一个类型由不同成分组成,成分具体不同可以组成不同类型的对象,抽象工厂可以定义生产这些成分的公共接口,而具体的工厂实现具体成分的生产。