设计模式(二)――工厂方法模式
一、工厂方法模式简介
1、工厂方法模式简介
工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法将一个类的实例化延迟到其子类。
对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,若增加了新的产品,只需相应增加工厂子类即可。
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得工厂方法可以被子类继承。
工厂方法模式特点:
(1)工厂方法模式是对简单工厂模式的稍微的改进。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。
(2)与简单工厂模式相比,制造产品的工厂类不再只有一个,而是每种具体产品类都对应一个生产它的具体工厂类。而具体工厂类的共同特征被提取出来形成一个抽象产品类,具体产品类都继承自抽象产品类。
(3)当需要增加一种产品的时候,需要做的是:增加一种继承自抽象产品的具体产品类,增加一种继承在抽象工厂的具体工厂类,更改客户端的逻辑判断。
UML类图如下:
2、工厂方法模式角色
工厂接口:抽象工厂是工厂方法模式的核心,与调用者直接交互用来提*品。工厂接口可以由抽象类来代替。
工厂实现:工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
产品接口:产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。
3、工厂方法模式优缺点
优点:
A、良好的封装性
B、良好的扩展性
C、屏蔽了产品类,用户不需要知道产品类的实例化过程。
D、实现解耦,符合迪米特法则
E、不用修改已有代码,开放封闭原则:对扩展开放,对更改封闭
缺点:
每增加一种产品,就需要增加一个对象的工厂。
4、工厂方法模式适用场景
A、作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
B、工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
C、工厂模式是依靠抽象架构的,把实例化产品的任务交由实现类完成,扩展性比较好。当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
D、当客户程序不需要知道要使用对象的创建过程。
E、客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。
在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色进行逻辑判断,而且产品对象创建条件的改变必然会引起工厂角色的修改。
二、工厂方法模式实现
IFactory抽象工厂类:
#ifndef IFACTORY_H
#define IFACTORY_H
#include "IProduct.h"
class IFactory
{
public:
virtual IProduct* createProduct() = 0;
};
#endif // IFACTORY_H
ConcreteFactoryA具体工厂A:
#include "IFactory.h"
#include "ConcreteProductA.h"
class ConcreteFactoryA : public IFactory
{
public:
ConcreteFactoryA(){}
IProduct* createProduct()
{
IProduct* product = new ConcreteProductA();
return product;
}
};
#endif // CONCRETEFACTORYA_H
ConcreteFactoryB具体工厂B:
#ifndef CONCRETEFACTORYB_H
#define CONCRETEFACTORYB_H
#include "IFactory.h"
#include "ConcreteProductB.h"
class ConcreteFactoryB : public IFactory
{
public:
ConcreteFactoryB(){}
IProduct* createProduct()
{
IProduct* product = new ConcreteProductB();
return product;
}
};
#endif // CONCRETEFACTORYB_H
IProduct抽象产品类:
#ifndef IPRODUCT_H
#define IPRODUCT_H
class IProduct
{
public:
virtual void show() = 0;
};
#endif // IPRODUCT_H
ConcreteProductA具体产品A:
#ifndef CONCRETEPRODUCTA_H
#define CONCRETEPRODUCTA_H
#include "IProduct.h"
#include <iostream>
using std::cout;
using std::endl;
class ConcreteProductA : public IProduct
{
public:
ConcreteProductA(){}
void show()
{
cout << "This is a ConcreteProductA" << endl;
}
};
#endif // CONCRETEPRODUCTA_H
ConcreteProductB具体产品类B:
#ifndef CONCRETEPRODUCTB_H
#define CONCRETEPRODUCTB_H
#include "IProduct.h"
#include <iostream>
using std::cout;
using std::endl;
class ConcreteProductB : public IProduct
{
public:
ConcreteProductB(){}
void show()
{
cout << "This is a ConcreteProductB" << endl;
}
};
#endif // CONCRETEPRODUCTB_H
客户端调用程序:
#include <iostream>
#include "IFactory.h"
#include "ConcreteFactoryA.h"
#include "ConcreteFactoryB.h"
using namespace std;
int main()
{
IFactory* factoryA = new ConcreteFactoryA();
IProduct* productA = factoryA->createProduct();
productA->show();
IFactory* factoryB = new ConcreteFactoryB();
IProduct* productB = factoryB->createProduct();
productB->show();
return 0;
}
三、工厂方法模式实例
1、计算器实例
UML类图:
代码实例:
#include <iostream>
#include <cstdlib>
using namespace std;
//抽象产品类
class Operation
{
protected:
double numberA;
double numberB;
public:
double getA()
{
return numberA;
}
double getB()
{
return numberB;
}
void setA(double number)
{
numberA = number;
}
void setB(double number)
{
numberB = number;
}
virtual double getResult()
{
double ret = 0;
return ret;
}
};
//具体产品类
class OperationAdd:public Operation
{
public:
double getResult()
{
double ret = 0;
ret = numberA + numberB;
return ret;
}
};
class OperationSub:public Operation
{
public:
double getResult()
{
double ret = 0;
ret = numberA - numberB;
return ret;
}
};
class OperationMul:public Operation
{
public:
double getResult()
{
double ret = 0;
ret = numberA * numberB;
return ret;
}
};
class OperationDiv:public Operation
{
public:
double getResult()
{
double ret = 0;
if(numberB != 0)
ret = numberA / numberB;
return ret;
}
};
//抽象工厂类
class AbstructFactory
{
public:
virtual Operation *CreateOperation()
{
return new Operation;
}
};
//具体工厂类
class AddFactory:public AbstructFactory
{
public:
Operation *CreateOperation()
{
Operation *oper = new OperationAdd;
return oper;
}
};
class SubFactory:public AbstructFactory
{
public:
Operation *CreateOperation()
{
Operation *oper = new OperationSub;
return oper;
}
};
class MulFactory:public AbstructFactory
{
public:
Operation *CreateOperation()
{
Operation *oper = new OperationMul;
return oper;
}
};
class DivFactory:public AbstructFactory
{
public:
Operation *CreateOperation()
{
Operation *oper = new OperationDiv;
return oper;
}
};
//客户端使用
int main(int argc, char *argv[])
{
AbstructFactory *af = NULL;
af = new AddFactory();
Operation *oper = NULL;
oper = af->CreateOperation();
oper->setA(2);
oper->setB(10);
cout << oper->getResult() << endl;
if(af != NULL)
{
delete af;
af = NULL;
}
if(oper != NULL)
{
delete oper;
oper = NULL;
}
return 0;
}
2、CPU工厂实例
生产处理器核的产家赚了不少钱,于是决定再开设一个工厂专门用来生产B型号的单核,而原来的工厂专门用来生产A 型号的单核。客户要做的是找好工厂,比如要A型号的核,就找A工厂要;否则找B工厂要,不再需要告诉工厂具体要什么型号的处理器核了。
class SingleCore
{
public:
virtual void Show() = 0;
};
//单核A
class SingleCoreA: public SingleCore
{
public:
void Show() { cout<<"SingleCore A"<<endl; }
};
//单核B
class SingleCoreB: public SingleCore
{
public:
void Show() { cout<<"SingleCore B"<<endl; }
};
class Factory
{
public:
virtual SingleCore* CreateSingleCore() = 0;
};
//生产A核的工厂
class FactoryA: public Factory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreA; }
};
//生产B核的工厂
class FactoryB: public Factory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreB; }
};
工厂方法模式也有缺点,每增加一种产品,就需要增加一个对象的工厂。如果公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。
本文出自 “生命不息,奋斗不止” 博客,谢绝转载!