什么是工厂模式的正确方法?

时间:2016-09-26 17:01:52

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

我一直在阅读很多关于工厂模式方法的东西,并且在所有工厂中似乎都有一个基于switch-case的静态方法在运行时返回所需的产品,但这似乎违反了每当有新产品时,打开关闭原则需要修改工厂类别以进行必要的更改。

下面是一个代码,我认为也符合工厂模式,但我不确定这种方法是否正确。基本上我认为客户将知道它需要什么类型的工厂,基于它的情况下获得工厂独自处理的产品,

如果这是正确的方法,或者有更好的方法,请告诉我。

#include "iostream"
#include "memory"
using namespace std;

class AbstractDog{
    public:
        virtual void bark(void) = 0;
        AbstractDog(){cout << "AbstractDog created"<<'\n';}
        virtual ~AbstractDog(){cout << "AbstractDog destroyed"<<'\n';}
};

class chiwawa : public AbstractDog{
    public:
        void bark(void){
            cout << "bark like chiwawa"<<'\n';
        }
        chiwawa(){cout << "chiwawa created"<<'\n';}
        virtual ~chiwawa(){cout << "chiwawa destroyed"<<'\n';}
};

class alsatian : public AbstractDog{
    public:
        void bark(void){
            cout << "bark like alsatian"<<'\n';
        }
        alsatian(){cout << "alsatian created"<<'\n';}
        virtual ~alsatian(){cout << "alsatian destroyed"<<'\n';}
};


class AbstractDogFactory{
    public:
        virtual AbstractDog* getDog(void) = 0;
        AbstractDogFactory(){cout << "AbstractDogFactory created"<<'\n';}
        virtual ~AbstractDogFactory(){cout << "AbstractDogFactory destroyed"<<'\n';}
};

class smallDogFactory : public AbstractDogFactory{
    public:
        virtual AbstractDog* getDog(void){
            return new chiwawa;
        }
        smallDogFactory(){cout << "smallDogFactory created"<<'\n';}
        virtual ~smallDogFactory(){cout << "smallDogFactory destroyed"<<'\n';}
};

class bigDogFactory : public AbstractDogFactory{
    public:
        virtual AbstractDog* getDog(void){
            return new alsatian;
        }
        bigDogFactory(){cout << "bigDogFactory created"<<'\n';}
        virtual ~bigDogFactory(){cout << "bigDogFactory destroyed"<<'\n';}
};


int main() {
    auto_ptr<AbstractDogFactory> m_ptr_fact(new bigDogFactory);
    auto_ptr<AbstractDog>        m_ptr_dog(m_ptr_fact->getDog());
    m_ptr_dog->bark();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

减少对工厂的代码更新的一种方法是使用带有函数指针的查找表(std::map也足够了)。

代码将在表中搜索键,然后执行(deference)指向函数的指针,该函数返回指向已创建实例的指针。

添加新类型的狗时,您将更新数据表。但是,您需要编写一个函数来返回指向dog实例的指针;因此工厂被修改了。但是,(查找表的)基本搜索功能不需要改变。

编辑1:
一个例子:

typedef (Abstract_Dog *) (*Dog_Creator_Func_Pointer)();
struct Table_Entry
{
  const char *  dog_name;
  Dog_Creator_Func_Pointer p_creator;
};
// Forward references
Abstract_Dog * Create_Greyhound();
Abstract_Dog * Create_Bulldog();
//...
static const Table_Entry creators[] =
{
  {"greyhound", Create_Greyhound},
  {"bulldog",   Create_Bulldog},
  //...
};
static const unsigned int creator_quantity =
  sizeof(creators) / sizeof(creators[0]);

//...
for (unsigned int i = 0; i < creator_quantity; ++i)
{
  if (dog_name == creators[i].dog_name)
  {
    return (*creators[i].p_creator)();
  }
}
return nulptr;