C++实现设计模式: Factory 工厂模式

来源:互联网 发布:域名冲突怎么解决 编辑:程序博客网 时间:2024/03/29 13:43

[译]C++实现设计模式: Factory 工厂模式

 

 


Definition 

Basically a Factory consists of an interface class which is common to all of the implementation classes that the factory will create. Then you have the factory class which is usually a singleton class that spawns instances of these implementation classes.

译文:

定义

一个典型的Factory 模式中一般包含一个接口类,所有的由工厂创造的实现类都继承自这个接口类。工厂类一般采用单例模式实现,由工厂类对象实例产生具体的实现类。

Abstract Interface Class

So let us create a quick interface class to start with. In this example, I used IAnimal

译文:

快让我们来创建一个接口类来开始我们的工厂模式之旅吧。在这个例子中,我们使用 IAnimal 来定义表示抽象动物的接口类。

class IAnimal{public:    virtual int GetNumberOfLegs() const = 0;    virtual void Speak() = 0;    virtual void Free() = 0;}; 

Now for simplicity’s sake, I used a typedef to define a type for the function that is used by the implementation classes to create instances of IAnimal. This typedef is also used in declaring the map that maps the animal name to the function that creates that particular type of animal. You can use whatever calling convention you like, but for this example, I chose __stdcall.

译文:

为了代码的简洁,我使用typedef 来定义一个函数指针,用于方便在工厂类中创建继承自IAnimal 类的子类对象实例。这个typedef 定义同样用在根据动物名称来影射创建具体动物对象的函数中。你可以根据你的使用习惯来定义它,但是我习惯上选择__stdcall来声明函数。

typedef IAnimal* (__stdcall *CreateAnimalFn)(void); 

Specific Implementation Class(es) 

Now come the implementation classes. These are the classes that implement the IAnimal interface. Here’re a few examples:

译文:

接着我们来定义具体实现的动物子类。这些类都实现了IAnimal 接口类。下面我们来看看几个例子:

// IAnimal implementationsclass Cat : public IAnimal{public:    int GetNumberOfLegs() const { return 4; }    void Speak() { cout << “Meow” << endl; }    void Free() { delete this; }    static IAnimal * __stdcall Create() { return new Cat(); }};class Dog : public IAnimal{public:    int GetNumberOfLegs() const { return 4; }    void Speak() { cout << “Woof” << endl; }    void Free() { delete this; }    static IAnimal * __stdcall Create() { return new Dog(); }};class Spider : public IAnimal // Yeah it isn’t really an animal…{public:    int GetNumberOfLegs() const { return 8; }    void Speak() { cout << endl; }    void Free() { delete this; }    static IAnimal * __stdcall Create() { return new Spider(); }};class Horse : public IAnimal{public:    int GetNumberOfLegs() const { return 4; }    void Speak() { cout << “A horse is a horse, of course, of course.” << endl; }    void Free() { delete this; }    static IAnimal * __stdcall Create() { return new Horse(); }};

Factory Class Declaration 

Now comes the Factory class. This is a singleton pattern implementation--meaning only one instance of the factory can ever be instantiated, no more, no less.

译文:

下面我们来定义工厂类。我们采用单例模式来实现,这意味着能且只有一个工厂类实例被创建。

// Factory for creating instances of IAnimalclass AnimalFactory{private:    AnimalFactory();    AnimalFactory(const AnimalFactory &) { }    AnimalFactory &operator=(const AnimalFactory &) { return *this; }    typedef map FactoryMap;    FactoryMap m_FactoryMap;public:    ~AnimalFactory() { m_FactoryMap.clear(); }    static AnimalFactory *Get()    {        static AnimalFactory instance;        return &instance;    }    void Register(const string &animalName, CreateAnimalFn pfnCreate);    IAnimal *CreateAnimal(const string &animalName);};

Factory Class Implementation

Now we need to work out a few definitions of the AnimalFactory class. Specifically the constructor, the Register, and the CreateAnimal functions.

译文:

现在我们来看看工厂类AnimalFactory 的成员函数定义。这里只分析默认构造函数,Register函数和 CreateAnimal 函数。

Constructor

The constructor is where you might consider registering your Factory functions. Though this doesn’t have to be done here, I’ve done it here for the purposes of this example. You could for instance register your Factory types with the Factory class from somewhere else in the code.

译文:

构造函数

构造函数中需要注册工厂类中的注册工厂函数(可以生成的动物种类)。虽然这些函数不是在这里完成,但是必须在工厂类的构造函数中注册。当然你也可以工厂类的其他函数中注册该工厂可以支持的类型对象实例化函数。

/* Animal factory constructor.Register the types of animals here.*/AnimalFactory::AnimalFactory(){    Register(“Horse”, &Horse::Create);    Register(“Cat”, &Cat::Create);    Register(“Dog”, &Dog::Create);    Register(“Spider”, &Spider::Create);}

Type Registration

Now let us implement the Register function. This function is pretty straightforward since I used a std::map to hold the mapping between my string (the animal type) and the create function.

译文:

类型注册

现在我们来实现注册成员函数。这个成员函数目标非常单一,我使用 std::map来影射动物类型名称和创建这个类型动物所需要的create 函数指针。

void AnimalFactory::Register(const string &animalName, CreateAnimalFn pfnCreate){    m_FactoryMap[animalName] = pfnCreate;}

Type Creation

And last but not least, the CreateAnimal function. This function accepts a string parameter which corresponds to the string registered in the AnimalFactory constructor. When this function receives “Horse” for example, it will return an instance of the Horse class, which implements the IAnimal interface.

译文:

类型创建

这里最后介绍CreateAnimal 函数(其他函数这里不做讲解),这个函数接受的第一个参数:字符串类型,代表在AnimalFactory 构造函数中注册了的可生成类型的名称(动物名称)。当这个函数收到参数“Horse”,工厂将要创建一个Horse类对象实例,这个类实现了IAnimal 接口。

IAnimal *AnimalFactory::CreateAnimal(const string &animalName){    FactoryMap::iterator it = m_FactoryMap.find(animalName);    if( it != m_FactoryMap.end() )    return it->second();    return NULL;}

Example Usage Program

最后,我们来看看工厂类的使用例子吧。

int main( int argc, char **argv ){    IAnimal *pAnimal = NULL;    string animalName;    while( pAnimal == NULL )    {        cout << “Type the name of an animal or ‘q’ to quit: “;        cin >> animalName;        if( animalName == “q” )        break;        IAnimal *pAnimal = AnimalFactory::Get()->CreateAnimal(animalName);        if( pAnimal )        {            cout << “Your animal has ” << pAnimal->GetNumberOfLegs() << ” legs.” << endl;            cout << “Your animal says: “;            pAnimal->Speak();        }        else        {            cout << “That animal doesn’t exist in the farm! Choose another!” << endl;        }        if( pAnimal )            pAnimal->Free();        pAnimal = NULL;        animalName.clear();    }    return 0
原文地址:http://m.blog.csdn.net/blog/johnnyelf83/8881439
原创粉丝点击