|
使用函数指针来代替 Switch 语句【以下是公司项目中部分的 videoSwitchAgent 】
使用一个单件的工程,将要创建的实体用不同的函数来表示,在这个工厂里面用一个 map 来保存所有创建实体的方法。由于 map 是可以链表结构没有大小限制,这样就可以做到便于扩充。
代码如下:
// EntityCreationFactory.h
namespace TA_IRS_App { class EntityCreationFactory { public: typedef TA_Base_Bus::IEntity* ( *CreatorFunction )( TA_Base_Core::IEntityDataPtr entityData ); static EntityCreationFactory& getInstance(); void registerFunction( const std::string& type, CreatorFunction function ); TA_Base_Bus::IEntity* createEntity( TA_Base_Core::IEntityDataPtr entityData ); private: EntityCreationFactory(); virtual ~EntityCreationFactory() {}; EntityCreationFactory( const EntityCreationFactory& theEntityCreationFactory ); EntityCreationFactory& operator=( const EntityCreationFactory& theEntityCreationFactory ); static TA_Base_Bus::IEntity* createCamera( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createVideoMonitor( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createVideoOutputGroup( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createQuad( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createBVSStage( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createSequence( TA_Base_Core::IEntityDataPtr entityData ); static TA_Base_Bus::IEntity* createRecordingUnit( TA_Base_Core::IEntityDataPtr entityData ); typedef std::map< std::string, CreatorFunction > FunctionMap; FunctionMap m_functions; static EntityCreationFactory* s_singleton; static TA_Base_Core::ReEntrantThreadLockable s_singletonLock }; // EntityCreationFactory } // TA_IRS_App //EntityCreeationFactory.cpp namespace TA_IRS_App { EntityCreationFactory* EntityCreationFactory::s_singleton = NULL; TA_Base_Core::ReEntrantThreadLockable EntityCreationFactory::s_singletonLock; EntityCreationFactory& EntityCreationFactory::getInstance() { if ( s_singleton == NULL ) { TA_Base_Core::ThreadGuard guard( s_singletonLock ); if ( s_singleton == NULL ) { s_singleton = new EntityCreationFactory(); } } return *s_singleton;
} EntityCreationFactory::EntityCreationFactory() { registerFunction( TA_Base_Core::Camera::getStaticType(), createCamera ); registerFunction( TA_Base_Core::VideoMonitor::getStaticType(), createVideoMonitor ); registerFunction( TA_Base_Core::VideoOutputGroup::getStaticType(), createVideoOutputGroup ); registerFunction( TA_Base_Core::Quad::getStaticType(), createQuad ); registerFunction( TA_Base_Core::BVSStage::getStaticType(), createBVSStage ); registerFunction( TA_Base_Core::Sequence::getStaticType(), createSequence ); registerFunction( TA_Base_Core::RecordingUnit::getStaticType(), createRecordingUnit ); } void EntityCreationFactory::registerFunction( const std::string& type, CreatorFunction function ) { TA_ASSERT( m_functions.end() == m_functions.find( type ), "A function is already registered for this type." ); m_functions[ type ] = function; } TA_Base_Bus::IEntity* EntityCreationFactory::createEntity( TA_Base_Core::IEntityDataPtr entityData ) { std::string type = entityData->getType(); LOG_GENERIC(SourceInfo, TA_Base_Core::DebugUtil::DebugInfo, "the type is %s", type.c_str()); FunctionMap::iterator it = m_functions.find( type ); if ( m_functions.end() == it ) { LOG_GENERIC( SourceInfo, TA_Base_Core::DebugUtil::DebugInfo, "Entity could not be created because it is of an unrecognised type: %s", type.c_str() ); return 0; } return it->second( entityData ); } // Private methods TA_Base_Bus::IEntity* EntityCreationFactory::createCamera( TA_Base_Core::IEntityDataPtr entityData ) { TA_Base_Bus::IEntity *pResult = NULL; return pResult; }
// Private methods TA_Base_Bus::IEntity* EntityCreationFactory::createCamera( TA_Base_Core::IEntityDataPtr entityData ) { TA_Base_Bus::IEntity *pResult = NULL; return pResult; } } // end TA_IRS_App // client TA_Base_Bus::IEntity *pEntity = EntityAccessFactory::getInstance().createEntity();
|