Qt GUI 和业务逻辑模块
Qt GUI and Business Logic modules
我想把这个项目Qt Calculator Example分成GUI模块和业务逻辑模块。最好的方法是什么?只用 C++ 编写逻辑模块是否更好,这样我也可以在其他 IDE 中使用它?
您的案例中的最佳实践或设计模式是 GRASP Controller 模式。
在您的情况下 - 这意味着您应将 class Calculator
与 Qt 内容(如 QWidget
)完全分开。
所以 - 如果您需要将 Calculator
中的内容呈现给 Qt 小部件 - 创建并使用像 CalculatorPresentationInterface
这样的界面。
要获取一些回调、计算器的 GUI 事件 - 创建回调槽或接口 CalculatorConrollerInterface
。
因此 - 您的计算器将实现 CalculatorConrollerInterface
以便能够从 GUI 接收事件。
使用 dependency injection pattern 通过 CalculatorConrollerInterface
将您的 Calculator
注入到您的 GUI。
你的 GUI 应该实现(或者你可以使用 adapter pattern)CalculatorPresentationInterface
并且你应该通过 CalculatorPresentationInterface
将你的 GUI 注入你的真实 Calculator
class .
这样,业务逻辑层(计算器)和表示逻辑层(Qt GUI)将彼此分离,您可以轻松地交换这两个层。
一个示例(每个 class 在单独的文件中)。
接口:
class CalculatorConrollerInterface
{
public:
virtual void onAdd() = 0;
virtual void onCurrentNumberChange(int number) = 0;
};
class CalculatorPresentationInterface
{
public:
virtual void showResult(int result) = 0;
};
计算器 - 不应与 Qt 有任何联系:
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 计算器介绍:
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
};
而你的主要:
#include "Calculator.hpp"
#include "QtCalculatorPresentation .hpp"
int main()
{
// dependency injections
QtCalculatorPresentation qtPresentation;
Calculator calculator(qtPresentation);
qtPresentation.setController(calculator);
qtPresentation.exec();
}
我想把这个项目Qt Calculator Example分成GUI模块和业务逻辑模块。最好的方法是什么?只用 C++ 编写逻辑模块是否更好,这样我也可以在其他 IDE 中使用它?
您的案例中的最佳实践或设计模式是 GRASP Controller 模式。
在您的情况下 - 这意味着您应将 class Calculator
与 Qt 内容(如 QWidget
)完全分开。
所以 - 如果您需要将 Calculator
中的内容呈现给 Qt 小部件 - 创建并使用像 CalculatorPresentationInterface
这样的界面。
要获取一些回调、计算器的 GUI 事件 - 创建回调槽或接口 CalculatorConrollerInterface
。
因此 - 您的计算器将实现 CalculatorConrollerInterface
以便能够从 GUI 接收事件。
使用 dependency injection pattern 通过 CalculatorConrollerInterface
将您的 Calculator
注入到您的 GUI。
你的 GUI 应该实现(或者你可以使用 adapter pattern)CalculatorPresentationInterface
并且你应该通过 CalculatorPresentationInterface
将你的 GUI 注入你的真实 Calculator
class .
这样,业务逻辑层(计算器)和表示逻辑层(Qt GUI)将彼此分离,您可以轻松地交换这两个层。
一个示例(每个 class 在单独的文件中)。
接口:
class CalculatorConrollerInterface
{
public:
virtual void onAdd() = 0;
virtual void onCurrentNumberChange(int number) = 0;
};
class CalculatorPresentationInterface
{
public:
virtual void showResult(int result) = 0;
};
计算器 - 不应与 Qt 有任何联系:
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 计算器介绍:
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
};
而你的主要:
#include "Calculator.hpp"
#include "QtCalculatorPresentation .hpp"
int main()
{
// dependency injections
QtCalculatorPresentation qtPresentation;
Calculator calculator(qtPresentation);
qtPresentation.setController(calculator);
qtPresentation.exec();
}