寻找更好的C级工厂

前端之家收集整理的这篇文章主要介绍了寻找更好的C级工厂前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个应用程序有几个对象(目前约有50个,但正在增长).应用程序中每个对象只有一个实例,这些实例在组件之间共享.

我所做的是从基础BrokeredObject类派生所有对象:

class BrokeredObject
{
  virtual int GetInterfaceId() = 0;
};

每个对象类型都返回一个唯一的ID.这些ID保存在头文件中.

然后我有一个ObjectBroker“工厂”.当有人需要一个对象时,请调用GetObjectByID(). boker在STL列表中查看该对象是否已存在,如果存在,则返回该对象.如果没有,它会创建它,将其放入列表并返回它.一切都很好.

BrokeredObject *GetObjectByID(int id)
{
  BrokeredObject *pObject;
  ObjectMap::iterator = m_objectList.find(id);
  // etc.
  if(found) return pObject;

  // not found,so create
  switch(id)
  {
    case 0: pObject = new TypeA; break;
    case 1: pObject = new TypeB; break;
    // etc.
    // I loathe this list
  }
  // add it to the list
  return pObject;
}

我觉得痛苦的是维护这个ID列表并让每个类实现它.我至少让我的消费者的生活变得更容易了,让每个类型都拥有关于它自己的ID的信息,如下所示:

class TypeA : public BrokeredObject
{
  static int get_InterfaceID() { return IID_TYPEA; }
  int GetInterfaceID() { return get_InterfaceID(); }
};

所以我可以得到一个像这样的对象:

GetObjectByID(TypeA::get_InterfaceID());

有必要实际知道ID映射是什么,但我仍然对维护和错误的可能性感到不满.似乎如果我知道类型,为什么我还要知道ID?

我渴望的是C#中的这样的东西:

BrokeredObject GetOrCreateObject<T>() where T : BrokeredObject
{
  return new T();
}

ObjectBroker将根据传入的类型创建对象.

C#已经破坏了我,这只是生活中的一个事实,C不能做到这一点,或者有没有办法实现这一点,我没有看到?

解决方法

是的,有一种方法.即使在C语言中C#代码也很简单(不检查继承):
template<typename T>
BrokeredObject * GetOrCreateObject() {
  return new T();
}

这将与C#代码一样工作和执行.它也是类型安全的:如果你传递的类型不是从BrokeredObject继承的(或者不是那个类型本身),那么编译器会在return语句中发出声音.但是它总是会返回一个新对象.

独生子

正如另一个人建议的那样(相信他),这一切看起来非常像单身人士模式的优秀案例.只需执行TypeA :: getInstance()即可获得存储在该类的静态变量中的单个实例和单个实例.我想这将比上述方法容易得多,而不需要ID来解决它(我之前展示了一种使用模板在这个答案中存储ID的方法,但我发现它实际上只是单身人士).

我已经读过你将有机会打开多个类的实例.一种方法是拥有一个Mingleton(我编造了这个词:))

enum MingletonKind {
    SINGLETON,MULTITON
};

// Singleton
template<typename D,MingletonKind>
struct Mingleton {
    static boost::shared_ptr<D> getOrCreate() {
        static D d;
        return boost::shared_ptr<D>(&d,NoopDel());
    }

    struct NoopDel {
        void operator()(D const*) const { /* do nothing */ }
    };
};

// Multiton
template<typename D>
struct Mingleton<D,MULTITON> {
    static boost::shared_ptr<D> getOrCreate() {
        return boost::shared_ptr<D>(new D);
    }
};

class ImASingle : public Mingleton<ImASingle,SINGLETON> {
public:
    void testCall() { }
    // Indeed,we have to have a private constructor to prevent
    // others to create instances of us.
private:
    ImASingle() { /* ... */ }
    friend class Mingleton<ImASingle,SINGLETON>;
};

class ImAMulti : public Mingleton<ImAMulti,MULTITON> {
public:
    void testCall() { }
    // ...
};

int main() {
    // both do what we expect.
    ImAMulti::getOrCreate()->testCall();
    ImASingle::getOrCreate()->testCall();
}

现在,您只需使用SomeClass :: getOrCreate(),它就会关注细节.对于shared_ptr,单例情况下的自定义删除操作使删除成为无操作,因为shared_ptr拥有的对象是静态分配的.但是,请注意静态变量的破坏顺序问题:Static initialization order fiasco

猜你在找的C&C++相关文章