Problem
目前的主流就是以composition代替inheritance,因此可以寫出這樣的程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| struct SubCompoent1 { int v = 100; int add(int num) { return v + num; } int sub(int num) { return v - num; } }; struct SubCompoent2 { int v = 300; int mul(int num) { return v * num; } int div(int num) { return v / num; } }; struct Component { Component() : comp1(new SubCompoent1), comp2(new SubCompoent2) {} std::unique_ptr<SubCompoent1> comp1; std::unique_ptr<SubCompoent2> comp2; int add(int num) { return comp1->add(num); } int sub(int num) { return comp1->sub(num); } int mul(int num) { return comp2->mul(num); } int div(int num) { return comp2->div(num); } }; int func(Component *comp) { return comp->add(300); } int func1(Component *comp) { return comp->div(5); }
|
這樣的程式碼很值觀,>不過問題也很明顯,一旦新增一個Function Call,接著又要改個地方
Possible Solution 1
將SubCompent的介面公開,然後提供一組介面存取SubComponent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| struct Component { Component() : comp1(new SubCompoent1), comp2(new SubCompoent2) {} std::unique_ptr<SubCompoent1> comp1; std::unique_ptr<SubCompoent2> comp2; SubCompoent1* getComp1() { return comp1.get(); } const std::unique_ptr<SubCompoent2>& getComp2() { return comp2; } }; nt func(Component *comp) { SubCompoent1* comp1 = comp->getComp1(); return comp1->add(300); } int func1(Component *comp) { const auto& comp2 = comp->getComp2(); return comp2->div(5); }
|
跟上面方式相比,少了每次新增API介面就要修改Component的煩惱,不過要為每組Subcomponent提供一組Access Function,試著將他自動化
Possible Solution 2
結合C++14的get和tuple之後,可以寫成這樣
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct Component { Component() : comp1(new SubCompoent1), comp2(new SubCompoent2) {} std::unique_ptr<SubCompoent1> comp1; std::unique_ptr<SubCompoent2> comp2; SubCompoent1* getComp1() { return comp1.get(); } const std::unique_ptr<SubCompoent2>& getComp2() { return comp2; } }; int func(Component *comp) { return comp->get<SubCompoent1>()->add(300); } int func1(Component *comp) { return comp->get<SubCompoent2>()->div(5); }
|
不過這樣還是需要輸出SubComponent的介面,在某些場合底下還是不太適用
不知道未來可不可以靠refelection和overload operator->
來寫出更好的程式碼