2016-11-18 45 views
1

我有類Foo,它有多個構造函數。更好的模式選擇構造函數

class Foo 
{ 
public: 
Foo(Param1, Param2); 
Foo(Param1, Param3, Param4); 
Foo(Param1, Param4); 
Foo(Param1, Param2, Param4); 
} 

PARAMS構造器的實際列表大,我不想提供訪問這些構造直接從其他項目(否則我也需要出口這4個構造函數)。我知道最好的模式,以避免這種多重構造是Builder Pattern。但是,這會給這個類的客戶造成混淆,哪些參數是可選的,哪些參數不是。另外每個構造函數都根據參數進行一定的驗證。所以在實際使用這個對象的任何方法之前,我需要通用的地方來做這樣的驗證。

所以目前我們正在開發的是如下的內容:

  1. 沒有變化Foo類。

  2. 定義FooParam結構

    struct FooParam 
    { 
        Param1 p1; 
        Param2 p2; 
        Param3 p3; 
        Param4 p4; 
    } 
    
  3. 廠:

    Foo* CreateFoo(FooParams& foo) 
    { 
        if(foo.Param2) 
        { 
         if(foo.Param4) 
         { 
          return new Foo(foo.param1, foo.param2, foo.param4); 
         } 
         else 
          return new Foo(foo.param1, foo.param2); 
        } 
        else if(foo.param4) 
        { 
         if(foo.param3) 
          return new Foo(foo.param1, foo.param3, foo.param4); 
         else 
          return new Foo(foo.param1, foo.param4); 
        } 
    
        throw new Exception("Invalid Parameter"); 
    } 
    

我想我們可以在第3步中做的更好,但現在知道怎麼辦?

+1

param1 ....的數據類型是什麼? –

+2

還有默認值的選項 –

+0

多重構造函數的優點是非常清楚哪些參數放在一起。 'struct FooParam'似乎使一切變得複雜。爲什麼你不能導出構造函數? – Gene

回答

-1

作爲一個用戶,我更喜歡

Foo* CreateFoo(Param1* P1, Param2* P2, Param3* P3, Param4* P4); 

我爲什麼要construc一個struct只是傳遞一些(也許NULL)的參數?

1

如果你不想暴露你的構造函數因爲某些原因,你可以很容易隱藏在他們身後基於模板和完美轉發的工廠方法:

class Foo { 
    // defined somewhere 
    Foo(Param1, Param2); 
    Foo(Param1, Param3, Param4); 
    Foo(Param1, Param4); 
    Foo(Param1, Param2, Param4); 

private: 
    template<typename... Args> 
    static auto factory(Args&&... args) { 
     Foo foo{std::forward<Args>(args)...}; 
     // do whatever you want here 
     return foo; 
    } 
} 

無需在運行時扔東西。
如果接受這些參數的構造函數不存在,您將收到編譯時錯誤。


否則,這樣做的另一種慣用方式是使用named constructors
我複製和粘貼直接的例子從上面的鏈接:

class Game { 
public: 
    static Game createSinglePlayerGame() { return Game(0); } 
    static Game createMultiPlayerGame() { return Game(1); } 

protected: 
    Game (int game_type); 
}; 

不知道這無論如何符合您的要求。


也就是說,想想什麼是這樣做的好處:

CreateFoo({ Param1V, Param3V }); 

或者更糟的是,這樣的:

FooParams params{ Param1V, Param3V }; 
CreateFoo(params); 

取而代之的是:

new Foo{Param1V, Param3V}; 

通過介紹一箇中級班實際上並沒有幫助你的班級的用戶。
他們仍然必須記住具體情況下所需的參數。