工厂方法模式
接上一篇博客,发现简单工厂模式存在一系列问题:
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
以上问题,在工厂方法模式中得到了改善,也即:简单工厂模式 + 开闭原则 = 工厂方法模式。
概念
工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
使用步骤:
使用步骤
步骤1: 创建抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
步骤3: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
类图角色和职责
抽象工厂(Creator)角色
工厂方法模式的核心,任何工厂类都必须实现这个接口。
具体工厂( Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
抽象(Product)角色
工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
工厂方法模式所创建的具体实例对象
工厂方法模式和简单工厂模式比较
工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。工厂方法模式退化后可以演变成简单工厂模式。
简单案例:
“开放-封闭”通过添加代码的方式,不是通过修改代码的方式完成功能的增强。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
/*简单工厂模式*/
class AbstractFruit{
public:
virtual void showName() = 0;
};
//实现类
class Apple :public AbstractFruit{
public:
virtual void showName(){
cout << "苹果。。。。。。。。。。" << endl;
}
};
class Banana :public AbstractFruit{
public:
virtual void showName(){
cout << "香蕉。。。。。。。。。。" << endl;
}
};
class Pear :public AbstractFruit{
public:
virtual void showName(){
cout << "鸭梨。。。。。。。。。。" << endl;
}
};
//抽象工厂
class AbstractFactory{
public:
virtual AbstractFruit* createObject() = 0;
};
//具体工厂——即:需要时增加新的具体工厂,不需要修改之前的代码
class AppleFactory : public AbstractFactory{
public:
virtual AbstractFruit* createObject(){
return new Apple;
}
};
class BananaFactory : public AbstractFactory{
public:
virtual AbstractFruit* createObject(){
return new Banana;
}
};
class PearFactory : public AbstractFactory{
public:
virtual AbstractFruit* createObject(){
return new Pear;;
}
};
void test01(){
AbstractFactory* factory = NULL;
factory = new AppleFactory;
AbstractFruit* fruit = factory->createObject();
fruit->showName();
delete fruit;
delete factory;
factory = new BananaFactory;
fruit = factory->createObject();
fruit->showName();
delete fruit;
delete factory;
factory = new PearFactory;
fruit = factory->createObject();
fruit->showName();
delete fruit;
delete factory;
fruit = NULL;
factory = NULL;
}
int main(void){
test01();
return 0;
}