go - 如何按照Clean Architecture在Golang中实现presenter?

标签 go architecture clean-architecture

正确的软件架构是创建可维护项目的关键。什么是适当的手段是 100% 主观的, 但最近我喜欢并尝试关注Clean Architecture作者:Robert C. Martin(又名鲍勃大叔)。

虽然我真的很喜欢这个理论,但它缺乏某种实用的实现指南来应对开发人员可能面临的常见技术挑战。 例如,我一直在努力解决的一件事是正确实现演示层。

演示者负责接受来 self 的用例的“响应”并以某种方式对其进行格式化 它可以“呈现”到我的输出设备(无论它是 Web 还是 CLI 应用程序)。

解决这个问题有多种方法,但它们通常属于以下类别之一:

  1. presenter 由用例本身通过某种输出接口(interface)调用
  2. 用例返回响应模型, Controller (最初称为用例)将此模型传递给演示者

选项 1 或多或少与 Clean Architecture/Uncle Bob 所说的相同(在本书和各种帖子中,见后面),选项 2 是一种可行的替代方法。

听起来很酷,但让我们看看如何在 Go 中实现它们。

这是我的第一个版本。为简单起见,我们的输出现在转到网络上。

另外,请原谅我的简洁。

package my_domain

import "http"

type useCase struct {
    presenter presenter
}

func (uc *useCase) doSomething(arg string) {
    uc.presenter("success")
}

type presenter interface {
    present(respone interface{})
}

type controller struct {
    useCase useCase
}

func (c *controller) Action(rw http.ResponseWriter, req *http.Request) {
    c.useCase("argument")
}

基本上它完全按照上面和 Clean Architecture 中的描述进行操作:有一个调用用例的 Controller (通过边界,此处不存在)。用例做某事并调用演示者(未实现,但这正是问题所在)。

我们的下一步可能是实现 presenter....但是鉴于输出在 Go HTTP 处理程序中的工作方式,有一个很好的问题需要解决。即:请求范围。

每个请求都有它自己的响应编写器(传递给 http 处理程序),响应应该写入其中。演示者没有可以访问的全局请求范围,它需要响应编写器。因此,如果我想遵循选项 1(调用演示者的用例),我必须以某种方式将它传递给演示者,演示者以这种方式成为请求范围,而应用程序的其余部分是完全无状态的并且不在请求范围内,它们被实例化一次.

这也意味着我要么将响应编写器本身传递给用例和呈现器(我宁愿不这样做),要么为每个请求创建一个新的呈现器。

我在哪里可以这样做:

  1. 通过工厂在 Controller 中
  2. 在通过工厂的用例中(但话又说回来:用例必须接收响应编写器作为参数)

这带来了另一个问题:如果演示者是请求范围的,用例也是吗?

如果我想将演示者注入(inject)到用例结构中,那么是的,并且还必须在 Controller 中创建用例。

或者,我可以使演示者成为用例的参数(没有人说必须在“构建时”注入(inject)依赖项)。但这仍然会在某种程度上将演示者与 Controller 耦合。

还有其他 Unresolved 问题(例如,我应该将 HTTP header 发送到哪里),但这些问题不太具体。

这是一个理论问题,因为我还不确定我是否想使用这种模式,但我已经花了相当多的时间思考这个问题,但到目前为止还没有找到完美的问题。

基于articles and questions我读过有关该主题的文章:其他人也没有。

最佳答案

我可以根据 Clean Architecture 告诉您我的经验。我花时间在那个问题上,阅读文章和测试代码。所以我想向您推荐以下帖子和所附的源代码,它对我帮助很大:

这是一个非常好的起点,我正在以这种方式设计我的软件,开发 Restful 网络应用程序,直到通过 jQuery 和 Bootstrap 向用户展示。我可以说,现在我的软件真正深入到了独立的层中。它还帮助我理解了 te golang 接口(interface)的强大功能,并最终对软件的每个部分进行了简单的测试。 希望这对您也有帮助。

关于go - 如何按照Clean Architecture在Golang中实现presenter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51119690/

相关文章:

c# - 是否有使用 DDD(领域驱动设计)的开源项目?

android - 优步如何向司机发送新的乘车请求?

Golang 事务性 API 设计

android - MVP with interactor and repository + rxjava 2. 在哪里调用 observeOn 和 subscribeOn

azure - 使用 Go 的 Azure ServiceBus 队列的 OpenTelemetry 传播问题

go - 当我们可以存储在字符串变量中时,缓冲区的用途是什么?

windows - 如何阻止 Golang 在执行 Windows 命令时用反斜杠替换双引号?

reflection - go中如何将结构体指针转换为类型指针列表

android - 将 REST API 调用置于 Uncle Bob 的 Clean Architecture 中的何处?

android - 使用 Dagger 2 和 setRetainInstance(true) 时获取 NullPointErexception;