与简单工厂模式相比,工厂模式为每个类增加了一个工厂类。每个工厂类返回它所对应的类的对象指针。
简单工厂模式的最大优点:工厂类中包含了必要的逻辑判断。根据客户端的选择条件动态的实例化相关的类。没有在客户端实现判断,也就去除了与客户端的依赖。
简单工厂模式实现计算类结构图:
工厂模式实现计算类结构图:
工厂模式实现代码:
#include<iostream>
using namespace std;
class Operation
{
public:
double num1;
double num2;
public:
Operation(double n1,double n2)
{
num1=n1;
num2=n2;
}
virtual double calculate()=0;
};
class AddOperation:public Operation
{
public:
AddOperation(double n1,double n2)
:Operation(n1,n2)
{
}
virtual double calculate()
{
return num1+num2;
}
};
class SubOperation:public Operation
{
public:
SubOperation(double n1,double n2)
:Operation(n1,n2)
{
}
virtual double calculate()
{
return num1-num2;
}
};
class Factory
{
public:
double n1;
double n2;
public:
Factory(double n1,double n2)
{
this->n1=n1;
this->n2=n2;
}
virtual Operation *CreateOperation()=0;
};
class AddFactory:public Factory
{
public:
AddFactory(double n1,double n2)
:Factory(n1,n2)
{
}
virtual Operation*CreateOperation()
{
return new AddOperation(n1,n2);
}
};
class SubFactory:public Factory
{
public:
SubFactory(double n1,double n2)
:Factory(n1,n2)
{
}
virtual Operation*CreateOperation()
{
return new SubOperation(n1,n2);
}
};
int main(int argc,char**argv)
{
double n1,n2;
cin>>n1>>n2;
cout<<AddFactory(n1,n2).CreateOperation()->calculate()<<endl;
cout<<SubFactory(n1,n2).CreateOperation()->calculate()<<endl;
return 0;
}
对于简单工厂模式而言,如果需要添加新的计算功能类,如乘方类,就需要在简单工厂类中添加case分支条件,修改了原来的类,这违背了开放封闭原则。基于此引入了工厂模式。
工厂模式:定义一个用于创建对象的接口,让子类决定实例化那个类。工厂方法模式是一个类的实例化延迟到其子类。此时整个结构没有修改的变化,只是有扩展的变化。这完全符合开放封闭原则。但工厂方法实现时,客户端就需要判断实例化哪个工厂来实现运算类。选择判断仍然是必须的,工厂方法模式将简单工厂内部的逻辑判断移到了客户端进行判断。
对于大话设计模式中的雷锋工厂的例子。使用简单工厂模式时,每次实例化学生类或是志愿者类时,都需要简单工厂类的代码。在使用工厂模式时,会为每个雷锋类派生类,如学生类和志愿者类,都创建一个工厂类,用于生成该类所对应的对象。增加类时,只需要增加代码就可以了。很好的体现了开放封闭原则。
工厂类与简单工厂类实现雷锋工厂代码对比:
#include<iostream>
using namespace std;
class LeiFeng
{
public:
LeiFeng()
{
}
virtual void sweep()=0;
virtual void wash()=0;
virtual void buyRice()=0;
};
class Student:public LeiFeng
{
public:
Student()
{
}
virtual void sweep()
{
std::cout<<"this student is sweeping now"<<std::endl;
}
virtual void wash()
{
std::cout<<"this student is washing now"<<std::endl;
}
virtual void buyRice()
{
std::cout<<"this student is buying rice now"<<std::endl;
}
};
class Volunteer:public LeiFeng
{
public:
Volunteer()
{
}
virtual void sweep()
{
std::cout<<"this Volunteer is sweeping now"<<std::endl;
}
virtual void wash()
{
std::cout<<"this Volunteer is washing now"<<std::endl;
}
virtual void buyRice()
{
std::cout<<"this Volunteer is buying rice now"<<std::endl;
}
};
class SimpleFactory
{
public:
LeiFeng *lf;
public:
SimpleFactory()
{
lf=NULL;
}
LeiFeng* createLeiFeng(int type)
{
switch(type)
{
case 1:
{
lf=new Student;
}
break;
case 2:
{
lf=new Volunteer;
}
break;
}
return lf;
}
};
class IFactory
{
public:
IFactory()
{
}
virtual LeiFeng*CreateLeiFeng()=0;
};
class StudentFactory:public IFactory
{
public:
StudentFactory()
{
}
virtual LeiFeng*CreateLeiFeng()
{
return new Student;
}
};
class VolunteerFactory:public IFactory
{
public:
VolunteerFactory()
{
}
virtual LeiFeng*CreateLeiFeng()
{
return new Volunteer;
}
};
int main(int argc,char**argv)
{
LeiFeng *lf;
/*
SimpleFactory *sf=new SimpleFactory;
lf=sf->createLeiFeng(1);
lf->sweep();
lf->wash();
lf->buyRice();
lf=sf->createLeiFeng(2);
lf->sweep();
lf->wash();
lf->buyRice();*/
lf=(new StudentFactory)->CreateLeiFeng();
lf->sweep();
lf->wash();
lf->buyRice();
lf=(new VolunteerFactory)->CreateLeiFeng();
lf->sweep();
lf->wash();
lf->buyRice();
return 0;
}
工厂模式克服了简单工厂模式违背开放封闭原则,保持了封装对象创建过程的优点。要更换对象时不需要做大的改动即可实现,降低了客户程序与产品对象的耦合度。