Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

reduce code duplication – factory design pattern

I have created a small chess game and implemented a factory class to produce game pieces. However, I realized that my implementation is not ideal, as every game piece is responsible for registering itself with the factory. For instance, the bishop registers itself with the following code:

// white bishop registration
bool Bishop::m_registerit_white =
Factory<GamePiece>::registerit
(
    'B', []()->std::unique_ptr<GamePiece>
    { return std::make_unique<Bishop>(WHITE); }
);

// black bishop registration
bool Bishop::m_registerit_black =
Factory<GamePiece>::registerit
(
    'b', []()->std::unique_ptr<GamePiece>
    { return std::make_unique<Bishop>(BLACK); }
);

My teacher pointed out that these registration calls result in A LOT of code duplication for each piece (I agree). He suggested that I reduce the duplication by creating a map between characters and their corresponding classes, so that I could call the class constructor when needed, instead of having each piece register itself with the factory.

I am not entirely sure how to implement this suggestion and would appreciate some guidance.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is my factory class:

template<typename T>
class Factory {

public:
    //the pointer to the function that creates the object
    using creationFunc = unique_ptr<T>(*)();

    //register a pair of char+creator function into the map:
    static bool registerit(const char& name, creationFunc f) {
        getMap().emplace(name, f);
        return true;
    }

    //creates the objects according to the char that represents it
    //(searches this char in the map):
    static unique_ptr<T> create(const char& name) {
        const auto& map = getMap();
        auto it = map.find(name);
        if (it == map.end())
            return nullptr;
        return it->second();
    }

private:
    static auto& getMap() {
        static map<char, creationFunc> map;
        return map;
    }
};

>Solution :

If all the pieces are constructed the same way you could create a templated utility function or class to perform the registration.

For example:

template <typename Piece>
struct PieceRegister
{
    PieceRegister(char white, char black)
    {
        Factory<GamePiece>::registerit
        (
            white, []()->std::unique_ptr<GamePiece>
            { return std::make_unique<Piece>(WHITE); }
        );

        Factory<GamePiece>::registerit
        (
            black, []()->std::unique_ptr<GamePiece>
            { return std::make_unique<Piece>(BLACK); }
        );
    }
};

PieceRegister<Bishop> bishopRegister('B', 'b');
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading