2011-08-24 194 views
1

我有一個大工廠,我試圖弄清楚如何使它看起來很漂亮。
有大約40個可能的對象/構造組合:C++和STL:構造函數工廠

if(algorithm == "SHA-1") 
    return new HashImpl<...>(algorithm, seed, size); 
if(algorithm == "SHA-224") 
    return new HashImpl<...>(algorithm, seed, size); 
if(algorithm == "SHA-256") 
    return new HashImpl<...>(algorithm, seed, size); 
... 
if(algorithm == "AES" || algorithm == "AES128") 
    return new BlockCipherImpl<...>(algorithm, seed, size); 
... 
if(algorithm == "HmacSHA1") 
    return new HmacImpl<...>(algorithm, seed, size); 
... 

有沒有把這個成一張地圖,這樣我至少可以廢除順序查找的方法嗎?我在解決如何使構造函數成爲函子時遇到問題。

編輯:該代碼可以在這裏找到:
http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/src/crypto/SecureRandomImpl.cpp,各地開始線路130

+0

您能否更具體地瞭解HashImpl的<...>? –

+0

您的代碼在返回的內容中沒有顯示出不同。不同的算法字符串有什麼不同?模板參數?構造函數的參數?哪個 ? –

+0

羅伯特和桑德 - 我的不好。我發佈了一個鏈接到實際的代碼。全部返回'BaseImplementation *'。 – jww

回答

5

沒有必要使用這些花哨新奇的地圖。

template <class Impl> 
BaseImplementation* makeAlgo (const std::string& algo, 
           const byte* seed, size_t size) 
{ 
    return new Impl(algo, seed, size); 
} 

typedef BaseImplementation* makeAlgo_t (const std::string& algo, 
              const byte* seed, size_t size); 

typedef struct { std::string name; makeAlgo_t func; } NamedAlgoMaker_t; 


NamedAlgoMaker_t factory[] = { 
    { "SHA-1",  makeAlgo< HashImpl <...> > }, 
    ... 
    { "HmacSHA1", makeAlgo< HmacImpl <...> > }, 
    ... 
}; 

如果保持數組排序,則可以使用二分查找快速查找算法。

當然,如果你願意,你也可以從這些東西中構建一張地圖(或散列/無序地圖)。

+0

+1,我喜歡這個簡單。 – molbdnilo

+0

@n.m .:不像我希望的那麼漂亮,但是我可以怪你醜陋的C++語法:) – jww

0

所以它仍然是視覺上難看。但您可以通過以下方式使其更快:

  1. 創建〜40個工廠方法,每個工廠方法返回其中一個選項。
  2. 創建一個映射,其中fnPointerTypedef是工廠方法的返回類型。
  3. 做一本字典查找,並返回你查找的任何功能的結果。
  4. 創建一個給出每個選項的數字的枚舉(例如SHA-1 = 0,SHA-224 = 1等)。
  5. 創建一個將字符串名映射到{int | enum}的映射。
  6. 創建一個函數指針數組,並讓數組中的每個點指向正確的相應工廠方法。
  7. 做字典查找並返回functionArray [enumInt];

(編輯:感謝N.M.進行更直接的實現)

+0

希望如果你打算這樣做,你知道如何做Vim宏或類似的東西 –

+2

沒有必要從字符串映射到int,然後從int映射到函數指針。從字符串到函數指針的直接映射將會完成。 –

1

您可以使用地圖lambda函數也許