簡體   English   中英

干凈的方法來使用模板基類來消除工廠類的派生類的冗余

[英]Clean way to use a template base class to eliminate redundancy on derived classes for a factory class

我正在嘗試創建一個抽象的工廠模式,我有兩個工廠,我們稱之為factoryA和factoryB。 我將使用struct而不是class來保存一些輸入。

對於某些繼承類的系列,讓我們從一些A類開始,

struct A
{
  // ...
};

struct derivedA1 : public A
{
  // ...
};

struct derivedA2 : public derivedA1
{
  // ...
};

現在讓我們為了說明的目的,與其他一些B類做同樣的事情。

struct B
{
  // ...
};

struct derivedB1 : public B
{
  // ...
};

struct derivedB2 : public derivedB1
{
  // ...
};

所以對於這些類,我正在嘗試創建一個工廠模式(注意,在我的工作中,我們使用自定義錯誤處理,我將調用error_handle_t,其實現應該無關緊要):

struct factoryA
{
    std::map<int, std::shared_ptr<A> > myMap;

    factoryA()
    {
        // setup values to search against
        myMap[0] = std::make_shared<A>();
        myMap[1] = std::make_shared<derivedA1>();
        myMap[2] = std::make_shared<derivedA2>();

        //...room for more
    }

    error_handle_t make_object(int key, std::shared_ptr<A>& object)
    {
        object = myMap[key];
        return ...
    }
};

struct factoryB
{
    std::map<int, std::shared_ptr<B> > myMap;

    factoryB()
    {
        // setup values to search against
        myMap[0] = std::make_shared<B>();
        myMap[1] = std::make_shared<derivedB1>();
        myMap[2] = std::make_shared<derivedB2>();
        //...room for more
    }

    error_handle_t make_object(int key, std::shared_ptr<B>& object)
    {
        object = myMap[key];
        return ...
    }
};

看起來“接口”抽象類可能是一個合適的基類,但每個工廠的返回類型不同。 並且A類和B類之間沒有共同的基類來使這項工作“很好”,所以我做不到

error_handle_t make_object(int key, std::shared_ptr<base_for_A_and_B>& object) = 0;

但上面的工廠看起來很漂亮,幾乎可以參數化

template <typename T>
struct base
{
    std::map<int, std::shared_ptr<T> > myMap;

    error_handle_t make_object(int key, std::shared_ptr<T>& object)
    {
        object = myMap[key];
        return ...

    }
};

根據Interface中的Override模板成員 ,我無法使模板類虛擬化為抽象類。

但是如果我們可以假設make_object的“算法”是相同的。 我在網上看到這可能是一個實用工具類

struct factoryA : private base<A>
{
    std::map<int, std::shared_ptr<A> > myMap;

    error_handle_t make_object(int key, std::shared_ptr<A>& object)
    {
        ...
        object = myMap[key];
        return ...
    }
};

但我沒有覆蓋模板庫,只是將其用作輔助函數。 沒有真正解決我想要實現的目標。

最終的目標是建立一個抽象的工廠

struct factories
{
    template <typename T>
    error_handle_t create(int key, shared_ptr<T>& object)
    {
        object = make_shared<T>()->make_object(key)
        return ...;
    }
};

而不是在沒有公共基類的情況下創建相同的對象。

struct factories
{
    // Initialize in ctor which I didn't include here
    factoryA concrete_factoryA;
    factoryB concrete_factoryB;

    error_handle_t createA(int key, shared_ptr<A>& object)
    {
       object = concrete_factoryA.make_object(key);
       return ...;
    }

    error_handle_t createB(int key, shared_ptr<B>& object)
    {
       object = concrete_factoryB.make_object(key);
       return ...;
    }
};

所以我必須創建一個創建方法,因為它包含許多工廠而沒有杠桿模板和類型扣除以一些干凈的方式。 想法或建議?

我想要的用法:

factories l_factories;
shared_ptr<A> a_ptr;
shared_ptr<B> b_ptr;

l_factories.create(0, a_ptr);
l_factories.create(1, b_ptr);

與我的相比:

factories l_factories;
shared_ptr<A> a_ptr;
shared_ptr<B> b_ptr;

l_factories.createA(0, a_ptr);
l_factories.createB(1, b_ptr);

你可能想要這樣的東西:

template <typename T>
struct factory
{
    error_handle_t create(int key, shared_ptr<T>& object)
    {
        object = make_shared<T>()->make_object(key)
        return ...;
    }
};

template <typename ... Facts>
struct factories : Facts...
{
    using Facts::create...; // C++17, but can be done in C++11 with recursion
};

using factoryA = factory<A>;
using factoryB = factory<B>;
using MyFactory = factories<factoryA, factoryB>;

在C ++ 11中, factories將是:

template <typename ... Facts> // Main declaration
struct factories {}; // Empty case

template <typename Fact>
struct factories<Fact> : Fact{};

template <typename Fact, typename ... Facts>
struct factories<Fact, Facts...> : Fact, factories<Facts...>
{
    using Fact::create;
    using factories<Facts...>::create;
};

接着

MyFactory l_factories;
shared_ptr<A> a_ptr;
shared_ptr<B> b_ptr;

l_factories.create(0, a_ptr);
l_factories.create(1, b_ptr);

公平地說,我不確定你在尋找什么...這應該是一個評論,而不是一個建議的答案,但這是我知道編寫格式正確的代碼的唯一方法。 請對不起我。

這句話讓我覺得你正在尋找類似的東西:

template<typename T>
struct factory<T>;

template<>
struct factory<A>
{
   std::shared_ptr<A> make_object()
   {
     // ...
   }

}; 

template<>
struct factory<B>
{
    std::shared_ptr<B> make_object()
    {
      // ...
    }
};

聽起來好嗎? 我不能說明派生類的作用是什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM