工厂模式
来源:互联网 发布:pyqt5 知乎编程 编辑:程序博客网 时间:2024/06/04 19:31
1 什么是工厂模式?
以下摘自维基百科
工厂方法模式(英语:Factorymethod pattern)是一种实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。”
创建一个对象常常需要复杂的过程,所以不适合包含在一个复合对象中。创建对象可能会导致大量的重复代码,可能会需要复合对象访问不到的信息,也可能提供不了足够级别的抽象,还可能并不是复合对象概念的一部分。工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题。由子类实现这个方法来创建具体类型的对象。
对象创建中的有些过程包括决定创建哪个对象、管理对象的生命周期,以及管理特定对象的创建和销毁的概念。
2 从理论到实际
Android中的MediaPlayerFactory是经典的简单工厂模式, 它是这么定义的:
class MediaPlayerFactory { public:class IFactory {…… }; static status_t registerFactory(IFactory* factory, player_type type); static void unregisterFactory(player_type type); private: typedef KeyedVector<player_type, IFactory*> tFactoryMap; static tFactoryMap sFactoryMap;};
MediaPlayerFactory有一个map即sFactoryMap来存储不同种类的Factory,包括StagefrightPlayerFactory,NuPlayerFactory,SonivoxPlayerFactory,TestPlayerFactory,如果有特殊需要,也可以定义一个新的Factory添加进来。
每个Factory都实现了于IFactory的接口,其中最重要的是ScoreFactory和CreatePlayer
class IFactory { public: virtual ~IFactory() { } virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, const char* /*url*/, float/*curScore*/) { return 0.0; } virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, int /*fd*/, int64_t/*offset*/, int64_t/*length*/, float/*curScore*/) { return 0.0; } virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, constsp<IStreamSource> &/*source*/, float/*curScore*/) { return 0.0; } virtual sp<MediaPlayerBase> createPlayer() = 0;};
应用程序一般会调用MediaPlayerFactory的getPlayerType函数
player_typeMediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, const char* url) { GET_PLAYER_TYPE_IMPL(client, url);}
在GET_PLAYER_TYPE_IMPL中,实际上就是根据url给sFactoryMap中的各个Factory打分,然后拿到得分最高的那个Factory。
#define GET_PLAYER_TYPE_IMPL(a...) \ Mutex::Autolock lock_(&sLock); \ player_type ret = STAGEFRIGHT_PLAYER; \ float bestScore = 0.0; \ for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ IFactory* v = sFactoryMap.valueAt(i); \ float thisScore; \ CHECK(v != NULL); \ thisScore = v->scoreFactory(a, bestScore); \ if (thisScore > bestScore) { \ ret = sFactoryMap.keyAt(i); \ bestScore = thisScore; \ } \ } \ if (0.0 == bestScore) { \ ret = getDefaultPlayerType(); \ } \ return ret;
得到对应的Factory后,调用这个它的createPlayer方法,获得对应的Player
class StagefrightPlayerFactory : public MediaPlayerFactory::IFactory { public:virtual floatscoreFactory(const sp<IMediaPlayer>& /*client*/, } virtual sp<MediaPlayerBase> createPlayer() { ALOGV(" create StagefrightPlayer"); return new StagefrightPlayer(); }};
而Player在初始化的时候,创建了另一个真正干活的player就是AwesomePlayer。
StagefrightPlayer::StagefrightPlayer() : mPlayer(new AwesomePlayer) { ALOGV("StagefrightPlayer"); mPlayer->setListener(this);}
3 总结
1. 当调用者需要一个产品时,直接传递一个参数给工厂,让工厂生产不同的产品。
2. 这些产品实现了同样的接口。
3. 调用者无需了解细节,只需要提要求(传参数)给工厂即可。
- 工厂模式 -- 工厂方法
- 工厂模式 -- 抽象工厂
- 工厂模式-简单工厂
- 工厂模式-工厂方法
- 工厂模式:静态工厂
- 工厂模式-简单工厂
- 工厂模式-抽象工厂
- 工厂模式-工厂方法
- 工厂 > 工厂方法模式
- 工厂模式-静态工厂
- 工厂模式-抽象工厂
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 工厂模式
- 黑马程序员——OC分类和本质探索
- 从SSL安全传输到iOS证书安全体系1
- 第五周项目三 程序的多文件组织
- Memcached的序列化处理保存数据
- poj1419Graph Coloring
- 工厂模式
- 第五周项目二:对象作为数据成员
- X264如何阅读数
- java同步器——1——笔记
- 所谓的 双向BFS
- tomcat加载Listener,Filter,Servlet顺序
- Socket编程笔记
- Ibatis 批量操作 和 三级下拉框连动问题
- Socket网络编程入门