2016-03-09 85 views
2

我想將此項目Qt Calculator Example分解爲GUI模塊和業務邏輯模塊。最好的方法是什麼?最好是隻用C++編寫邏輯模塊,以便我可以在其他IDE中使用它?Qt GUI和業務邏輯模塊

+0

MVC模式,結合模型不應該使用Qt類型的規則,將帶您走向正確的方向。 –

回答

1

您的案例中的最佳做法或設計模式是GRASP Controller模式。

在你的情況 - 這意味着你應該完全從Qt的東西(如QWidget)分開類Calculator

所以 - 如果您需要將Calculator中的某些內容呈現給Qt小部件 - 請創建並使用像CalculatorPresentationInterface這樣的界面。

要獲得一些回調,計算器的GUI事件 - 使回調插槽,或接口CalculatorConrollerInterface

因此 - 您的計算器將執行CalculatorConrollerInterface以便能夠從GUI接收事件。

使用dependency injection pattern將您的Calculator通過CalculatorConrollerInterface注入您的GUI。

你的GUI應執行(或者你可以使用adapter patternCalculatorPresentationInterface,你應通過CalculatorPresentationInterface注入你的圖形用戶界面,以自己的真實Calculator類。

通過這種方式,兩層業務邏輯層(計算器)和表示邏輯(Qt GUI)將相互分離,您可以輕鬆地交換兩個層。


一個例子(每個類在單獨的文件中)。

接口:

class CalculatorConrollerInterface 
{ 
public: 
    virtual void onAdd() = 0; 
    virtual void onCurrentNumberChange(int number) = 0; 
}; 
class CalculatorPresentationInterface 
{ 
public: 
    virtual void showResult(int result) = 0; 
}; 

計算器 - 無權Qt的任何關聯:

class QtCalculatorPresentation : public CalculatorPresentationInterface 
{ 
public: 
    void setController(CalculatorConrollerInterface& controller) 
    { 
     this->controller = &controller; 
    } 
    void showResult(int result) override; 

private: 
    CalculatorConrollerInterface* controller; 
    // plus all Qt widgets necessary 
    // and they shall forward any event to controller 
}; 

你的主:

class Calculator : public CalculatorConrollerInterface 
{ 
public: 
     Calculator(CalculatorPresentationInterface& presentation) 
     : presentation(presentation) 
     {} 
    virtual void onAdd() override 
    { 
     // no idea this is correct - just example 
     previousNumber = previousNumber + currentNumber; 
     currentNumber = 0; 
     presentation.showResult(previousNumber); 
    } 

    void onCurrentNumberChange(int number) override 
    { 
      currentNumber = number; 
    } 
private: 
     CalculatorPresentationInterface& presentation; 
     // all stuff necessary to calculate 
     int previousNumber; 
     int currentNumber; 
}; 

的Qt演示了計算器

#include "Calculator.hpp" 
#include "QtCalculatorPresentation .hpp" 

int main() 
{ 
     // dependency injections 
     QtCalculatorPresentation qtPresentation; 
     Calculator calculator(qtPresentation); 
     qtPresentation.setController(calculator); 

     qtPresentation.exec(); 
} 
+0

鑑於Qt是一個應用程序開發框架,對保持業務邏輯不使用Qt的癡迷是恕我直言,沒有根據。你在信號/插槽,內省,線程,消息傳遞(事件)等方面失敗了......對於計算器業務對象,你應該使用狀態機,如QStateMachine,因爲這些事情*很難得到正確的結果,並且帶有錯誤功能的示例代碼在網絡上幾乎無處不在,正是因爲人們不願意指定系統的狀態圖。 –

+0

使用Qt,你不需要使用虛擬方法指定接口的固定接口類的straitjacket。使用信號/插槽連接異質客戶端和提供商非常容易;仿函數可以用來使不合格的提供者適應客戶的需求等等。就我而言,傳統的「作爲抽象類的接口」模式非常不靈活,並且很難使用(或者缺少! )當你與第三方代碼交互時。通常這些接口不是作爲抽象類給出的,而是隻有一個實現定義API的具體類。 –

+0

@KubaOber - 1)在C++ 14 + boost中,你可以想象Qt將會提供的一切。 2)如果你確實需要一些qt狀態機/ qt定時器等等。 - 然後以同樣的方式你可以在Qt中創建一個 - 並通過C++接口連接到你的「業務控制器」 - 因此它可以使用抽象定時器等... – PiotrNycz