工厂方法模式(Factory Method Pattern)是简单工厂模式的进一步抽象
工厂方法模式的实质是:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
工厂方法模式中,工厂类被提升为抽象类,并将具体的创建工作交给子类。这个抽象的工厂类仅规定了具体工厂必须实现的接口,而不明确指出如何实例化一个产品类,这使得工厂方法模式可以不修改原有产品结构的情况下引进新产品
2. 基本结构工厂方法模式的基本结构如下UML图所示:
这里以C++为例给出实现代码:
class Product {
};
class Factory {
virtual Product createProduct() = 0;
};
class ConcretProduct: public Product {
};
class ConcretFactory: public Factory {
Product createProduct override {
// 创建具体商品~
return new ConcretProduct();
}
};
4. demo
4.1 应用描述
随着多媒体技术的不断发展,各类多媒体格式层出不穷,每种格式通常都需要特定的解码器解码后才能播放出来。以Windows自带的媒体播放器(MediaPlayer)为例,它可以用来播放多种音频及视频格式。无论想听.mp3格式的音乐还是.wma格式的音乐,都可以用一个MediaPlayer打开并进行回放。以视听者的角度来看,这些文件没有差别,但其依赖于特定的解码器类型(Decoder),只有使用对应的解码器进行解码才能将该多媒体回放出来
现假定有.mp3和.wma两种格式的音频文件,尝试模仿MediaPlayer的工作过程
4.2 实现代码前一节采取了简单工厂模式,这里采用工厂方法模式实现:
#include "bits/stdc++.h"
using namespace std;
class Product {
public:
virtual void decode() = 0;
};
class Mp3Decoder : public Product {
public:
string fileName;
explicit Mp3Decoder(string fileName) {
this->fileName = fileName;
this->decode();
}
void decode() override {
cout << "[type: .mp3]" << this->fileName << "start decoding!" << endl;
}
};
class WmaDecoder : public Product {
public:
string fileName;
explicit WmaDecoder(string fileName) {
this->fileName = fileName;
this->decode();
}
void decode() override {
cout << "[type: .wma]" << this->fileName << "start decoding!" << endl;
}
};
class Factory {
public:
virtual Product *createDecoder(string fileName) = 0;
};
class Mp3DecoderFactory : public Factory {
public:
Product *createDecoder(string fileName) override {
return new Mp3Decoder(fileName);
}
};
class WmaDecoderFactory : public Factory {
public:
Product *createDecoder(string fileName) override {
return new WmaDecoder(fileName);
}
};
int main() {
string fileName = "One Last Kiss.mp3";
Factory *factory = new Mp3DecoderFactory();
factory->createDecoder(fileName);
return 0;
}
5. 优点
- 使得客户端不再绑定到与特定应用有关的类上
- 将所要创建的具体对象的实例化延迟到子类,较好地解决了紧耦合
- 把简单工厂内部判断逻辑转移到了客户端代码来进行,换取了原有类结构的稳定
- 维护代码代价小
- 客户端需要选择实例化的工厂类
- 为了一个特定产品类,不得不创建新的具体工厂
- 当一个类不知道它必须创建的对象的类的信息时
- 当一个类希望由它子类来指定它创建的对象时
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类时代理者这一信息局部化时
- 连接具有平行结构的类层次时



