Explicit Architecture(清晰架构)整合六边形架构和洋葱架构

让架构清晰的展现出来

用户界面,这里的代码就是为了适配某个用例的传达机制;
用户核心,这里的代码就是用例和领域逻辑;
基础设施,这里的代码就是为了适配应用核心所需要的工具、库。
在这里插入图片描述
因此,在源码的目录下面,我们可以创建三个文件夹来提现三类代码。这个三个文件夹分别表示三个命名空间,核心代码对用户界面和基础设施是可见的,这就是由外向内的依赖方式。

用户界面

在一个web应用中通常有多套API。例如,一套给客户端使用的REST API,还有一套给第三方应用使用的web-hook,业务还有一套需要维护的遗留SOAP API,或者还有一套给全新移动应用的GraphQL API…
在这里插入图片描述
用户界面主要有三大类:API,CLI,网站。所以我们可以在UserInterface根命名空间下为每个类别创建一个文件夹,如上图所示。

核心

在Core命名空间下,按照最粗粒度来分成三类代码:组件(component)、共享内核(shared kernel)、端口(port)。

组件

在component命名空间下,为每个组件创建一个命名空间,然后在各组的命名空间下,我们再分别为应用层和领域层创建空间。在application和domain命名空间下,我们会将全部的类放在一起,随着类的不断增加,我们在考虑分组。
在这里插入图片描述
这时候我们就要考虑按照业务主体(收据、交易、对账…)分组还是按照技术作用(仓库、服务、值对象…)分组。

端口

和infrastructure命名空间一样,port命名空间里核心使用的每一种工具都有一个命名空间,核心通过这些代码才能使用底层的工具
在这里插入图片描述
这些代码会被适配器使用,他们的作用就是端口和真正的工具之间的转换。这种形式简单得不能再简单了,端口就是一个接口,但是很多时候它还需要值对象、DTO、服务、构建器、查询对象甚至是仓库。

共享内核

我们把组件之间共享的代码放到shared kernel命名空间下。
在这里插入图片描述

基础设施

和用户界面一样,我们的应用使用了多种工具(库和第三方应用),例如ORM、消息队列、SMS提供商。因此,在infrastructure命名空间里,就需要创建(ORM、MessageQueue、SmsClient),然后为每种工具添加对应的适配器。
在这里插入图片描述
最终的代码结构就是:
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的示例: 首先,在Qt Creator中创建一个新的Qt Quick应用程序项目。然后,在项目文件夹中创建以下文件夹:`model`,`view`和`viewModel`。 在`model`文件夹中创建一个名为`User`的C++类,用于存储用户信息,例如用户名和密码。在`User`类中定义以下成员变量和方法: ```c++ class User : public QObject { Q_OBJECT Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) public: explicit User(QObject *parent = nullptr); QString username() const; void setUsername(const QString &username); QString password() const; void setPassword(const QString &password); signals: void usernameChanged(); void passwordChanged(); private: QString m_username; QString m_password; }; ``` 在`User`类的实现文件中,实现上述成员变量和方法的具体内容。 在`viewModel`文件夹中创建一个名为`LoginViewModel`的C++类,用于处理用户登录逻辑。在`LoginViewModel`类中定义以下成员变量和方法: ```c++ class LoginViewModel : public QObject { Q_OBJECT Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) public: explicit LoginViewModel(QObject *parent = nullptr); QString username() const; void setUsername(const QString &username); QString password() const; void setPassword(const QString &password); signals: void usernameChanged(); void passwordChanged(); public slots: void login(); private: QSharedPointer<User> m_user; }; ``` 在`LoginViewModel`类的实现文件中,实现上述成员变量和方法的具体内容。在`login`方法中,实现用户登录逻辑。 在`view`文件夹中创建一个名为`LoginPage`的Qt Quick界面,用于显示登录界面和处理用户输入。在`LoginPage`中使用`TextField`组件显示用户名和密码输入框,并使用`Button`组件显示登录按钮。在`LoginPage`中定义以下属性和方法: ```qml Item { property string username: "" property string password: "" TextField { placeholderText: "Username" text: username onTextChanged: root.username = text } TextField { placeholderText: "Password" text: password onTextChanged: root.password = text } Button { text: "Login" onClicked: login() } function login() { //TODO: call login() method in LoginViewModel } } ``` 在`LoginPage`中,当用户点击登录按钮时,调用`login`方法,该方法将调用`LoginViewModel`中的`login`方法,以处理用户登录逻辑。 最后,在`main.cpp`中创建一个`QQmlApplicationEngine`对象,并将`LoginPage`作为根组件加载到该引擎中。然后,将`LoginViewModel`实例化并设置为`LoginPage`的`contextProperty`,以便在Qt Quick界面中访问该对象。 ```c++ #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "viewModel/LoginViewModel.hpp" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; //Instantiate LoginViewModel object LoginViewModel loginViewModel;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值