工厂模式:工厂类太大时该怎么办?

时间:2016-09-01 08:28:33

标签: c++ design-patterns factory-pattern component-based

我正在使用实体基础组件系统。

我有很多类型RETURN QUERY EXECUTE format ('SELECT foocolumn FROM footable HERE foocolumnother LIKE %L' ', concat(footext, '%')); ,例如

  
      
  1. Wall = blocks
  2.   
  3. Fire Turret = block + shooter
  4.   
  5. Water Turret = blocks + shooter
  6.   
  7. Bunker = blocks + spawner
  8.   

以下是lister=["AB1","AB2","AB3","AB3-2","AB3-3","AB3-4","AB4","AB4-2","AB5"] resulter = list() i=0 while i< len(lister)-1: if '-' not in lister[i] and '-' not in lister[i+1]: resulter.append(lister[i]) elif '-' not in lister[i] and '-' in lister[i+1]: j=i+1 tmp = lister[j] while '-' in tmp and j<len(lister)-1 and lister[i][2] == lister[j+1][2]: j += 1 tmp = lister[j] i=j resulter.append(tmp) i+=1 if lister[-1] not in resulter: resulter.append(lister[-1]) print(resulter) 的工厂: -

stationary objects

它的效果非常好。

问题:
现在我要创建100种stationary objects类型,我应该在哪里存储它? 将所有这些存储在课程class StationaryObject{ enum typeOfObject_enum{WALL,FIRE_TURRET, ....}; Entity* create(typeOfObject_enum theType){ //it is enum switch(theType){ case WALL: ... create some mesh, some physic body .... case FIRE_TURRET: .... create some mesh, some physic body+ unique logic 20 lines .... .... } } } 中会使课程太大(?)。

请注意,每种类型的对象都有微小但唯一的逻辑。

2 个答案:

答案 0 :(得分:4)

您可以创建从typeOfObject_enum到每个对象工厂的地图,然后您可以根据需要在地图中注册工厂。

每个对象工厂都可能像std::function<std::unique_ptr<Entity>()>

enum class StationaryObjectType{WALL, FIRE_TURRET, WATER_TURRET};
const size_t STATIONARY_OBJECT_TYPE_COUNT = 3;
using EntityFactory = std::function<std::unique_ptr<Entity>()>;

class StationaryObjectFactory {
    std::array<EntityFactory, STATIONARY_OBJECT_TYPE_COUNT> factory_map; 
public:
    void registerFactory(StationaryObjectType type, EntityFactory factory){
        factory_map[static_cast<size_t>(type)] = std::move(factory); 
    }
    std::unique_ptr<Entity> create(StationaryObjectType type){
        auto factory = factory_map[static_cast<size_t>(type)];
        if (!factory)
            return nullptr;
        return factory();
    }
};

int main() {
    StationaryObjectFactory factory;

    // Register lambdas as the factory objects
    factory.registerFactory(StationaryObjectType::WALL, []{
        return std::make_unique<Wall>(); 
    });    
    factory.registerFactory(StationaryObjectType::FIRE_TURRET, []{
        return std::make_unique<FireTurret>(); 
    });

    auto wall = factory.create(StationaryObjectType::WALL);    
    auto fire_turret = factory.create(StationaryObjectType::FIRE_TURRET);
    auto water_turret = factory.create(StationaryObjectType::WATER_TURRET);

    assert(wall != nullptr);    
    assert(fire_turret != nullptr);
    assert(water_turret == nullptr);  // No WATER_TURRET factory registered
}

Live demo.

或者如果您愿意,可以使用抽象工厂类的实现:

class EntityFactory {
public:
    virtual ~EntityFactory(){}
    virtual std::unique_ptr<Entity> operator()() = 0;
};

class WallFactory : public EntityFactory {
public:
    std::unique_ptr<Entity> operator()() override {
        return std::make_unique<Wall>();
    }
};

class FireTurretFactory : public EntityFactory {
public:
    std::unique_ptr<Entity> operator()() override {
        return std::make_unique<FireTurret>();
    }
};

Live demo.

答案 1 :(得分:1)

我没有使用过C ++,但听起来你可以混合使用构建器和工厂模式来获得你想要的东西,

class StationaryObject{
    Entity create(typeOfObject_enum theType){ //it is enum
        switch(theType){
            case WALL:
                return WallBuilder.Build();
            case FIRE_TURRET:
                return FireTurrentBuilder.Build();
            ....
        }
    }
}

您可以通过添加基类BaseBuilder来优化它,其中您对不同的实体具有任何通用逻辑

class BaseBuilder<T> {
   Mesh CreateMesh(){...}

   ....

   T Build();
}

class WallBuilder : BaseBuilder<Wall> {
   Wall Build(){
   }
}

使用这种方法,如果你想要你可以使用枚举和构建器之间的映射,并摆脱案例陈述