2015-06-26 75 views
2

我的類層次結構:多個子類層次結構

class AbstractProcess 
{ 
    virtual void Do() = 0; 
}; 

class BuildProcess : public AbstractProcess 
{ 
    virtual void Do(); 
}; 

class UpdateProcess : public AbstractProcess 
{ 
    virtual void Do(); 
}; 

然而,我現在要介紹的2新的子類作爲一個過程也可以是手動或自動的(4?)。下面看起來是太長篇大論:

class ManualBuildProcess : public BuildProcess 
{ 
    virtual void Do(); 
}; 

class ManualUpdateProcess : public UpdateProcess 
{ 
    virtual void Do(); 
}; 

class AutomatedBuildProcess : public BuildProcess 
{ 
    virtual void Do(); 
}; 

class AutomatedUpdateProcess : public UpdateProcess 
{ 
    virtual void Do(); 
}; 

如果我要介紹的另外兩種亞型構建/更新或手動/自動處理這隻會變得更糟。

有更好的設計嗎?

+0

C++支持多繼承,因此您可以擁有另一個處理手動工作常用功能的基類,以及一個處理自動工作常用功能的基類。這將意味着更多的類,但它也可能意味着更好的抽象,以及葉類中的更少的代碼。 –

+0

引入手動/自動化過程是否使前面的類變得抽象?我的意思是,你是否仍然想使用不好的'BuildProcess' w/o來指定它是手動還是自動? –

+0

Andy T - 是的,這是一個很好的觀點。手動和自動化子類現在變得抽象。 –

回答

1

我可以建議兩種方法。

一個是讓你Manual...Process模板:

template<class Process> class ManualProcess: public Process { 
    virtual void Do() { 
     ... 
     // you can access base class data: 
     Process::Do(); 
    } 
}; 

// use like 
ManualProcess<BuildProcess> process; // instead of ManualBuildProcess 

其次,有兩個層次,並喜歡在繼承組成,像

class Operator; 
class ManualOperator: public Operator... 
class AutomaticOperator: public Operator... 

class Process { 
    Operator* operator; 
    ... 
}; 
class BuildProcess: public Process... 
class UpdateProcess: public Process... 
... 

或反之亦然(Operator拿着指針Process),或者甚至以對稱的方式與Operator s和Process彼此不知道,但第三類持有指向Operator和一個指向Process的指針。

當然,這一切只適用於有一些通用於所有Manual箱子和一些代碼通用於所有Build案件等如果每個的這些版本都有它自己的代碼的代碼,那麼你顯然沒有選擇。

0

C++允許多重繼承。這可能會讓班級結構更好,但是在這樣的背景下,很難說什麼是最好的。

但是您可能會想到將自動化進程和ManualProcess直接作爲AbstractProccess的子類,就像構建過程和UpdateProcess一樣。

但是,如果所有的組合都存在,那麼您將不得不爲每個組合創建一個類,仍然會導致您現在擁有的類的數量。

您可能想要考慮一下自動/手動過程的功能。 它可能不需要是一個單獨的類,但它可能是一個類的成員。

0

我會盡量減少繼承和使用組合。 Manual/Automated是一個平面,Build/Update是另一個平面。好像你的Process需要雙飛機中定義的策略。這是可以做到的:

struct Executor; 
struct Operator; 

template <typename ExecutorT, typename OperatorT> 
struct Process 
{ 
    std::unique_ptr<Executor> executor_; 
    std::unique_ptr<Operator> operator_; 

    Process(): 
     executor_(new ExecutorT()), 
     operator_(new OperatorT()) 
    {} 

    void Do() 
    { 
     executor_->Do(); 
     operator_->Do(); 
     // do something else 
    } 
}; 

其餘部分是相當簡單的,現在你可以專注於業務邏輯:

struct Executor 
{ 
    virtual void Do() = 0; 
}; 

struct Manual : Executor 
{ 
    virtual void Do() override {} 
}; 

struct Automated : Executor 
{ 
    virtual void Do() override {} 
}; 

struct Operator 
{ 
    virtual void Do() = 0; 
}; 

struct Build : Operator 
{ 
    virtual void Do() override {} 
}; 

struct Update : Operator 
{ 
    virtual void Do() override {} 
}; 
0

除了像例如vaious面向對象的方法strategy pattern,你可以使用ALO中的模板C++:

template <typename Action> class Process { 
    Action a; 
    public: 
     Process(const Action& action): a{action} {}; 
     void do() { a.do(); }; 
}; 

template <typename Interface> class BuildAction { 
    Interface i; 
    public: 
     BuildAction(const Interface& interface): i{intreface} {}; 
     BuildAction(const BuildAction& other): i{other.i} {}; 
     void do() { i.build(); }; 
}; 

template <typename Interface> class UpdateAction { 
    Interface i; 
    public: 
     UpdateAction(const Interface& interface): i{intreface} {}; 
     UpdateAction(const UpdateAction& other): i{other.i} {}; 
     void do() { i.update(); }; 
}; 

class ManualInterface { 
    public: 
     void build(); 
     void update(); 
}; 

class AutomaticInterface { 
    public: 
     void build(); 
     void update(); 
}; 

typedef Process<BuildAction<ManualInterface>>  ManualBuildProcess; 
typedef Process<BuildAction<AutomaticInterface>> AutomaticBuildProcess; 
typedef Process<UpdateAction<ManualInterface>> ManualUpdateProcess; 
typedef Process<UpdateAction<AutomaticInterface>> AutomaticUpdateProcess; 

我可能對您的實際USECASE一些不理想的假設。BTW

Process<ManualInterface> myManualBuildProcess{BuildStrategy{}}; 

:我已經使用C++語法11:你可能會找到更好的結構,如例如: -

typedef Process<BuildAction, ManualInterface> ManualBuildProcess; 

當然你也可以用面向對象的模式以及結合模板。如果你只有C++ 98,你必須相應地調整代碼。