05. Abstract Factory Pattern + Reflection–AbstractFactory&Reflect

Hits: 0

Abstract Factory pattern (AbstractFactory) and reflection technology (Reflect) are recorded in the previous notes, and now the two functions are combined. Take the food in the fast food restaurant as an example.

First of all, there are foods from fast food restaurants as the base category of products, and then there are two types of food: drumsticks and hamburgers, and drumsticks and hamburgers are divided into KFC and McDonald’s. The hamburgers and drumsticks of KFC and McDonald’s are different, which means they are different implementation types, which are suitable for the use of abstract factories.

See the specific implementation code below:

// ReflectFactory.h

#pragma once
#include <string>

typedef void* (*lpCreateInstanceFun)();
typedef struct tagClassInfoData
{
    std::string strClassName;
    lpCreateInstanceFun pFun;
    tagClassInfoData* pNext;
}ClassInfoData;

class CReflectFactory
{
private:
    static ClassInfoData* pData;
    static ClassInfoData* pHead;
    static CReflectFactory _tmp_;

public:
    CReflectFactory(void);
    ~CReflectFactory(void);
    static void AddInstance(const std::string& strClassName, lpCreateInstanceFun pFun);
    static void* GetInstance(const std::string& strClassName);
};

#define DECLARE_REFLECT(CLASS_NAME) private:\
    static void* _CreateInstance_(){ return new CLASS_NAME(); }\
    static wchar_t _m_AddFunc_;\
    static wchar_t _AddFunc_() { CReflectFactory::AddInstance(#CLASS_NAME, &_CreateInstance_); return 0; }

#define IMPLEMENT_REFLECT(CLASS_NAME) wchar_t CLASS_NAME::_m_AddFunc_ = _AddFunc_();

// ReflectFactory.cpp

#include ".\ReflectFactory.h"

ClassInfoData* CReflectFactory::pData = NULL;
ClassInfoData* CReflectFactory::pHead = NULL;
CReflectFactory CReflectFactory::_tmp_;

CReflectFactory::CReflectFactory(void)
{
}

CReflectFactory::~CReflectFactory(void)
{
    ClassInfoData* pFind = pHead;
    while ( pFind != NULL )
    {
        pFind = pHead->pNext;
        delete pHead;
        pHead = pFind;
    }
}

void CReflectFactory::AddInstance(const std::string& strClassName, lpCreateInstanceFun pFun)
{
    if ( NULL != pFun )
    {
        if ( NULL == pData )
        {
            pData = new ClassInfoData();
            pHead = pData;
        }
        else
        {
            pData->pNext = new ClassInfoData();
            pData = pData->pNext;
        }
        pData->strClassName = strClassName;
        pData->pFun = pFun;
        pData->pNext = NULL;
    }
}

void* CReflectFactory::GetInstance(const std::string& strClassName)
{
    std::string str = strClassName;
    ClassInfoData* pFind = pHead;
    while ( pFind != NULL )
    {
        if ( str == pFind->strClassName )
        {
            return pFind->pFun();    // Don't forget the parentheses
        }
        pFind = pFind->pNext;
    }
    return NULL;
}

//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_

#include <string>
#include "ReflectFactory.h"

// Food for fast food restaurants 
class  AbstractProduct 
{
 DECLARE_REFLECT(AbstractProduct);
public:
 virtual ~AbstractProduct();
protected:
 AbstractProduct();
private:
};


class AbstractProductA : public AbstractProduct
{
 DECLARE_REFLECT(AbstractProductA);
public:
 virtual ~AbstractProductA();
protected:
 AbstractProductA();
private:
};

class AbstractProductB : public AbstractProduct
{
 DECLARE_REFLECT(AbstractProductB);
public:
 virtual ~AbstractProductB();
protected:
 AbstractProductB(); private:
};

// KFC's drumstick 
class  ProductA1 : public AbstractProductA
{
 DECLARE_REFLECT(ProductA1);

public:    
 ProductA1();
 ~ProductA1();
protected: private:
};

// McDonald's drumstick 
class  ProductA2 : public AbstractProductA
{
 DECLARE_REFLECT(ProductA2);

public:
 ProductA2();
 ~ProductA2();
protected: private:
};


// KFC's Burger 
class  ProductB1 : public AbstractProductB
{
 DECLARE_REFLECT(ProductB1);

public:
 ProductB1();
 ~ProductB1();
protected:
private:
};


// McDonald's hamburger 
class  ProductB2 : public AbstractProductB
{
 DECLARE_REFLECT(ProductB2);

public:
 ProductB2();
 ~ProductB2();
protected: private:
};
#endif //~_PRODUCT_H_ECT_H_


//Product.cpp
#include "Product.h"
#include <iostream>
using namespace std;

IMPLEMENT_REFLECT(AbstractProduct);
AbstractProduct::AbstractProduct()
{
 cout << "AbstractProduct...food for fast food restaurants" << endl ;
}

AbstractProduct::~AbstractProduct()
{
}

IMPLEMENT_REFLECT(AbstractProductA);
AbstractProductA::AbstractProductA()
{
}

AbstractProductA::~AbstractProductA()
{
}

IMPLEMENT_REFLECT(AbstractProductB);
AbstractProductB::AbstractProductB()
{
}

AbstractProductB::~AbstractProductB()
{
}

IMPLEMENT_REFLECT(ProductA1);
ProductA1::ProductA1()
{
 cout << "ProductA1...Kentucky Fried Chicken" << endl ;
}

ProductA1::~ProductA1()
{
}

IMPLEMENT_REFLECT(ProductA2);
ProductA2::ProductA2()
{
 cout << "ProductA2...McDonald's Drumsticks" << endl ;
}

ProductA2::~ProductA2()
{
}

IMPLEMENT_REFLECT(ProductB1);
ProductB1::ProductB1()
{
 cout << "ProductB1...KFC's Burger" << endl ;
}

ProductB1::~ProductB1()
{
}

IMPLEMENT_REFLECT(ProductB2);
ProductB2::ProductB2()
{
 cout << "ProductB2...McDonald's Burger" << endl ;
}

ProductB2::~ProductB2()
{
}


// main.cpp

#include "ReflectFactory.h"
#include "Product.h"

int main()
{
 AbstractProduct* p0 = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("AbstractProduct"));
 AbstractProduct* pA = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("AbstractProductA"));
 AbstractProduct* pB = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("AbstractProductB"));

 AbstractProduct* pA1 = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("ProductA1"));
 AbstractProduct* pA2 = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("ProductA2"));
 AbstractProduct* pB1 = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("ProductB1"));
 AbstractProduct* pB2 = static_cast<AbstractProduct*>(CReflectFactory::GetInstance("ProductB2"));

 return 0;
}

The power of reflection can be seen from the client code in the main function. Customers do not need to know any information other than the product name, nor do they need to know the specific factory information for creating the product, and in the internal code of the factory, it also avoids the need to use select or branch statements for different products in the Factory mode to achieve specific The product code better satisfies the OCP (see “02. Factory Pattern–Factory”).

You may also like...

Leave a Reply

Your email address will not be published.