设计模式之工厂方法模式(Factory Method)
简单工厂模式,又称为静态工厂方法模式(staticfactory method),除了单件模式之外,大约是23种Gof归纳的常见模式之中最简单的一种了。简单的讲,它就是用工厂类的一个静态方法来创建对象。这样,我们可以做到利用工厂类的静态方法统一管理对象的创建。
静态方法根据传入的字符串参数决定创建哪一个具体的对象,这样,客户端只需要知需要告诉工厂,它需要什么对象,工厂就会根据客户端的指令创建相应的对象实例,实现了客户端和对象创建的分离,解开了两者之间的耦合。
静态工厂推迟了对象的实例化。因为静态工厂是根据传入的字符串决定对象的实例化,所以我们可以通过配置文件决定工厂所创建的具体对象,这样我们可以通过配置文件修改代码的行为而无需对代码进行重新编译。
我们还是来看一个实际的例子。比如我们要创建一批音乐盒,包括可以播放小提琴音乐的音乐盒和播放钢琴音乐的音乐盒。使用简单工厂模式,我们可以将这个创建过程实现如下:
#include "stdafx.h" #include <string> #include <iostream> #include <memory> using namespace std; // 抽象的产品类 class IMusicBox { public: virtual void playMusic() = 0; }; // 具体的产品 class ViolinBox : public IMusicBox { public: void playMusic() { cout<<"播放小提琴音乐"; } }; class PianoBox : public IMusicBox { public: void playMusic() { cout<<"播放钢琴音乐"; } }; // 工厂类 class MusicBoxFactory { public: // 工厂类的静态方法 // 这个方法根据传入的字符串参数返回创建的对象 static IMusicBox* createMusicBox(string strName) { IMusicBox* pBox = NULL; if("Violin" == strName) { return new ViolinBox(); } else if( "Piano" == strName) { return new PianoBox(); } else { return nullptr; } } }; int _tmain(int argc, _TCHAR* argv[]) { // 创建对象 shared_ptr pBox( MusicBoxFactory::createMusicBox("Violin")); pBox->playMusic(); // 利用工厂创建新的对象 pBox.reset(MusicBoxFactory::createMusicBox("Piano")); pBox->playMusic(); return 0; } #include "stdafx.h" #include <string> #include <iostream> #include <memory> using namespace std; // 抽象的产品类 class IMusicBox { public: virtual void playMusic() = 0; }; // 具体的产品 class ViolinBox : public IMusicBox { public: void playMusic() { cout<<"播放小提琴音乐"; } }; class PianoBox : public IMusicBox { public: void playMusic() { cout<<"播放钢琴音乐"; } }; // 工厂类 class MusicBoxFactory { public: // 工厂类的静态方法 // 这个方法根据传入的字符串参数返回创建的对象 static IMusicBox* createMusicBox(string strName) { IMusicBox* pBox = NULL; if("Violin" == strName) { return new ViolinBox(); } else if( "Piano" == strName) { return new PianoBox(); } else { return nullptr; } } }; int _tmain(int argc, _TCHAR* argv[]) { // 创建对象 shared_ptr pBox( MusicBoxFactory::createMusicBox("Violin")); pBox->playMusic(); // 利用工厂创建新的对象 pBox.reset(MusicBoxFactory::createMusicBox("Piano")); pBox->playMusic(); return 0; }
从这里我们也可以看到,简单工厂模式的实现也非常简单,首先创建一个抽象的产品类,这里的IMusicBox,工厂方法需要利用这个抽象类来代表它所创建的产品,而不用管到底是什么产品。然后分贝实现具体的产品,ViolinBox和PianoBox,也就是我们具体要创建的对象。最后创建一个工厂类MusicBoxFactory并实现一个静态的函数,这个函数接受一个字符串作为参数,这个字符串就是客户端的指令,这个函数将根据这个字符串创建具体的产品。
这样,客户端只需要告诉简单工厂,它需要什么对象,就能够从工厂获得这个对象实例。对象的创建工作,都由简单工厂来完成了。
当然,简单工厂也还是有一定的局限,比如,它使用简单的实符串比较来决定要创建的对象,当工厂负责创建的对象增多时,将是一个很麻烦的事情。Gof后面总结的抽象工厂和工厂方法都是对简单工厂模式的某种形式上的升级,弥补了简单工厂的某些缺点。将这三个模式对比起来学习,将更加有助于我们更好的理解这三个创建型模式。
补充:软件开发 , C++ ,