目录
什么是工厂方法?
answer:是一种实现了工厂概念的面向对象的设计模式,是处理在不指定对象具有具体类型的情况下创建对象的问题。工厂方法是简单工厂方法的进一步抽象和推广。由于使用了编程语言的多态性,工厂方法保持了简单工厂模式的优点,同时,克服了它的缺点。
怎样实现工厂方法?
answer:在简单工厂模式的基础上,再添加一个工厂的接口,然后将不同对象的获取封装于工厂的派生类之中,及封装于小工厂之中,小工厂之中封装了得到不同对象的方法。通过添加小工厂的来添加不同的对象。在以计算器为例,分析一下用工厂方法实现计算器的UML图。
只是在简单的工厂上添加了一个工厂的抽象类。
工厂方法使用实例(计算器)
# include<iostream>
using namespace std;
//定义一个基类
class Operation
{
public:
void setA()
{
double num;
cout << "请输入第一个数:";
cin >> num;
numA = num;
}
double getA()
{
return numA;
}
void setB()
{
double num;
cout << "请输入第一个数:";
cin >> num;
numB = num;
}
double getB()
{
return numB;
}
//虚函数实现动态绑定
virtual double getResult()
{
return 0.0;
}
private:
double numA;
double numB;
};
//通过继承基类获得四个产品
class OperationAdd : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() + Operation::getB());
}
};
class OperationSub : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() - Operation::getB());
}
};
class OperationMuti : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() *Operation::getB());
}
};
class OperationDiv : public Operation
{
public:
virtual double getResult()
{
try
{
int a = 0;
if (Operation::getB() == 0.0)
{
throw a;
}
}
catch (int)
{
cout << "除数不能为!!!" << endl;
}
return (Operation::getA() /Operation::getB());
}
};
/*工厂方法对简单工厂做了进一步抽象, 多了一个Factory类,这个类将不再负责具体的产品生产,
而是只制定一些规范,具体的生产工作由其子类工厂去完成去完成。
再进行进一步的理解:就相当于汽车制造商其实只是从许多子制造工厂购买零件,再进行组装,将比较细化的操作交给底层
去做,自己只通过接口来获得零件。
*/
//定义一个大的工厂
class Factor
{
public:
virtual Operation * createOperation() = 0;
};
class FactorAdd :public Factor
{
public:
Operation * createOperation()
{
return new OperationAdd();
}
};
class FactorSub :public Factor
{
public:
Operation * createOperation()
{
return new OperationSub();
}
};
class FactorMuti :public Factor
{
public:
Operation * createOperation()
{
return new OperationMuti();
}
};
class FactorDiv :public Factor
{
public:
Operation * createOperation()
{
return new OperationDiv();
}
};
int main()
{
//先创建一个工厂 因为要动态绑定 用基类的工厂的指针或者引用去接受
//用一个大工厂去接收小工厂
Factor *factoy = new FactorDiv();
//用基类指针去接受派生类的对象
Operation *op = factoy->createOperation();
//调用相关的操作
op->setA();
op->setB();
cout<<"结果为:"<<op->getResult()<<endl;
system("pause");
return 0;
}
工厂方法VS简单工厂模式
这里举一个实例来说明:
在简单工厂模式中,如果需要增加一种新的运算为M的N次方,那么我们除了需要增加一个能创建这种对象的类,还要修改工厂类中的逻辑方法,等于是上一层和下一层的代码都要进行修改,这样就违反了开闭原则。
在工厂方法中,如果需要增加一种新的运算为M的N次方,需要增加一个类,然后只需要再增加一个工厂用来获取新的这种对象,最顶层的工厂的接口是不会变的,这就很好的体现了开闭原则。具体代码如下:
int main()
{
//先创建一个工厂 因为要动态绑定 用基类的工厂的指针或者引用去接受
//用一个大工厂去接收小工厂
Factor *factoy = new FactorDiv();
//用基类指针去接受派生类的对象
Operation *op = factoy->createOperation();
//调用相关的操作
op->setA();
op->setB();
cout<<"结果为:"<<op->getResult()<<endl;
system("pause");
return 0;
}
在需要不同的对象的时候,我们只需要改 Factor *factoy = new FactorDiv();即可,如我们需要加法操作只需要将这句代码改为:Factor *factoy = new FactorAdd();即可。