我们如何向基于原型的工厂提供具体对象?

问题描述 投票:0回答:1

Loki 库提供了用于构建 AbstractFactory 模式的预定义接口。我特别对基于原型的抽象工厂感兴趣。

假设我们有一个具有抽象实体的游戏应用程序:

class Soldier{ };
class Monster{ };
class SuperMonster{ };

和具体实体:

class EasySoldire : public Soldier{ };

class EasyMoster : public Monster{ };

class EasySuperMonster : public SuperMonster{ };

等等

Medium
Hard

现在我想创建基于原型的简易工厂。

这是它在 Loki 中的实现方式(Alexandrescu 的现代 C++ 设计):

template
<
    class AbstractFact,
    template <class, class> class Creator,
    class TList = typename AbstractFact::ProductList
>
class ConcreteFactory;

template <class ConcreteProduct, class Base>
class PrototypeFactoryUnit : public Base
{
    typedef typename Base::ProductList BaseProductList;
protected;
    typedef typename Base::ProductList TailProductList;
public;
    typedef typename Base::ProductList::Head AbstractProduct;
    PrototypeFactoryUnit(AbstractProduct* p = 0)
   :pPrototype_(p) {}
    friend void DoGetPrototype(const PrototypeFactoryUnit& me,
                                AbstractProduct*& pPrototype)
    {
        pPrototype = me.pPrototype_;
    }

    friend void DoSetPrototype(PrototypeFactoryUnit& me,
                               AbstractProduct* pObj)
    {
        me.pPrototype_=pObj;
    }

    template <class U>
    void GetPrototype(AbstractProduct*& p)
    {
        return DoGetPrototype(*this, p);
    }

    template <class U>
    void SetPrototype(U* pObj)
    {
        DoSetPrototype(*this, pObj);
    }

    AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
    {

       assert(pPrototype_);
       return pPrototype_->Clone();
    }
    private:
    AbstractProduct* pPrototype_;
};

所以 ConcreteFactory 看起来像:

typedef AbstractFactory
<
     TYPELIST_3(Soldier, Monster, SuperMonster)
>
AbstractEnemyFactory;

typedef ConcreteFactory
<
    AbstractEnemyFactory,
    PrototypeFactoryUnit
>
EnemyFactory;

现在我的问题是我们如何从具体工厂定义

Easy
级别工厂?

c++ templates c++-loki
1个回答
0
投票

我建议:

EnemyFactory easyFactory;
easyFactory.SetPrototype<EasySoldier>(new EasySoldier);
easyFactory.SetPrototype<EasyMonster>(new EasyMonster);
easyFactory.SetPrototype<EasySuperMonster>(new EasySuperMonster);
Soldier* pSoldier = easyFactory.Create<Soldier>();
Monster* pMonster = easyFactory.Create<Monster>();
SuperMonster* pSuperMonster = easyFactory.Create<SuperMonster>();

注意,Loki 的原型工厂要求类层次结构的所有元素都定义一个 Clone 方法,即:

class Enemy
{
  virtual Enemy* Clone() const = 0;
  virtual ~Enemy() {}
};

class Soldier : public Enemy
{
public:
  virtual Soldier* Clone() const override = 0;
  virtual ~Soldier() {}
};

class EasySoldier : public Soldier
{
public:
  EasySoldier* Clone() const override { return new EasySoldier(*this); };
};

等等。

© www.soinside.com 2019 - 2024. All rights reserved.