We're sunsetting PodQuest on 2025-07-28. Thank you for your support!
Export Podcast Subscriptions
People
J
Jeff
使用ChatGPT来改善关系和解决争论
P
Peter
Topics
Jeff: 我在博客中阐述了为什么不建议在SwiftData中使用query属性包装器。它违反了关注点分离原则,导致代码更脆弱、更不灵活。我将通过一个任务列表应用的例子,解释如何通过关注点分离避免代码问题。直接在视图中使用从API获取的数据会导致代码耦合,当API发生变化时,视图层也需要修改。如果API发生变化,直接在视图中使用API数据会导致视图层需要大量修改,这说明代码没有遵循关注点分离原则。关注点分离原则的核心是每个代码块只应对一个关注点负责。代码同时处理API契约和UI展示逻辑会导致代码耦合,违反了关注点分离原则。为了实现关注点分离,应该将数据模型分为数据模型(用于数据传输)和领域模型(用于应用内部逻辑)。数据模型(DTO)应该精确地反映API契约,不多不少。Postel定律(稳健性原则)建议在发送数据时保守,在接收数据时宽松。数据模型的字段应该尽可能地允许为空,以应对API变化。不要在数据模型中添加API协议无法表示的类型。即使API返回的是字符串,也应在数据模型中将其作为字符串处理,避免在数据模型中进行类型转换。领域模型应该适合应用内部使用,可以包含应用需要的复杂类型和业务逻辑。领域模型可以包含非可选值、更复杂的类型(如日期)和枚举类型,以满足应用内部的需求。视图模型是领域模型的一种常见类型,它专门用于在视图中显示数据。对于简单的应用,数据模型和视图模型可能就足够了;对于复杂的应用,可能需要额外的领域模型层来协调数据模型和视图模型之间的转换。不应该直接将API数据传递给视图,而应该通过领域模型进行转换。可以使用仓库模式来处理与API的通信,并使用数据映射器在数据模型和领域模型之间进行转换。仓库模式中,外部代码只与领域模型交互,数据模型只在仓库内部使用。数据映射器用于在数据模型和领域模型之间进行转换,并处理转换过程中的错误。 Peter: 关注点分离使代码更容易测试,并且在API或业务逻辑发生变化时,只需要修改少量代码。关注点分离使得代码更容易测试,因为可以独立测试各个模块。关注点分离使得代码更容易应对变化,因为只需要修改少量代码。缺乏关注点分离会导致大型代码迁移非常困难。关注点分离允许不同的团队并行开发,减少团队之间的依赖。关注点分离允许在后端完成之前开始前端开发。如果依赖后端数据才能进行开发,则说明设计存在问题。在设计应用时,应该提前考虑可能发生的API变化,并使用关注点分离来减少技术债务。关注点分离可以限制问题的影响范围,避免因为一个模块的改变而导致整个应用需要修改。

Deep Dive

Shownotes Transcript

在本集中,我们讨论了 Geoff 的一篇博文,该博文深入探讨了如何构建代码库并预防未来问题的细节。(00:00) - 介绍 (10:01) - 支持播客 (21:50) - SetApp - 200 多个 Mac 应用程序 (23:06) - 这如何帮助测试 Geoff 的博文关注点分离稳健性原则/波斯特尔法则成为 Patreon 会员并帮助此播客生存https://www.patreon.com/compileswift 感谢我们每月的支持者

Adam Wulf bitSpectre Arclite

★ 在 Patreon 上支持此播客 ★ </context> <raw_text>0 大家好,欢迎收听另一期播客。本周我们将讨论 Jeff 的一篇博文后续内容。他谈到了 Swift 数据和关注点分离,我们认为,你知道什么,这将成为一集好节目。所以让我们首先说,Jeff,你好吗,伙计?你这一周过得怎么样?

我很好。幕后工作有点多。我们实际上是在上一集播客三天后录制的这一集。所以实际上并没有太多时间发生任何事情。是的,剧透警告。对。是的。

是的,三天内没有任何事情变得更好,对吧?基本上这就是我们想说的。好吧,让我们开始吧。所以你发布了一篇博文。当然,朋友们,我们会在节目说明中添加链接。而且,你知道,对于那些不知道关注点分离是什么的人来说,我认为这将很有趣,并且可能会引发一些讨论,对吧?根据我在 Discord 上看到的。再说一次,我们会在节目说明中添加链接。所以,Jeff,开始吧。

是的,这一切都是这样发生的。这篇博文是 Discord 中的人们强烈要求的,因为我花相当长的时间抨击 Swift 数据中的 query 属性包装器。人们真的说,嘿,你知道,如果你这么讨厌 query,为什么你这么讨厌 query?解释一下你为什么讨厌它,为什么你认为它不好,等等等等。

所以由此产生了一篇博文,它本质上是,你知道,有点过分主观,但是,你知道,这就是你这些天做的事情。对。是的。这就是让我们收听的原因,因为我们是主观的。他们不在乎真相。是的。

基本上是说,嘿,不要在 SwiftData 中使用 query 属性包装器,因为它会使你的代码更脆弱。它会使你的代码更不灵活。如果你不使用它,使用 SwiftData 会更容易。原因是关注点分离的概念。

所以我想我们要做的是提取那些通用的部分,那些适用于你使用的任何语言、任何框架的博文部分,并真正讨论一下,为什么这很重要?你如何实现它?以及通过实现这样的东西你能获得什么好处?是的。首先,我想说,对,我在我的 Swift 数据中使用了 query。

并非我广泛使用过 Swift 数据,而且我没有遇到问题。所以,你知道,我想我会站在另一边。你用它发布过应用程序吗?这实际上是一个很好的问题,因为我今天一直在考虑这个问题。你真的完成过发布吗?我吗?这实际上是在上周末出现的,因为有人问我关于 Job Finder Tracker 的问题。Job Finder Tracker 确实使用了 Swift 数据。所以,是的,我想答案是肯定的,我用过。而且我已经成功地卖给了……

一些人。所以我想这没问题。是的。是的。不,我的意思是,如果你现在正在使用 query,而且你没有遇到任何问题,你不需要现在就将其全部拆解。但是,嗯,我绝对认为它会鼓励一些不良行为,而且我认为它或多或少应该避免,即使 Apple 确实试图推动它,因为它使他们的代码在 WWDC 幻灯片上看起来很漂亮。是的。

一切都是为了看起来漂亮。我认为我将在本集中做的是提供一个示例,一个我可以在音频形式中讨论并逐步讲解的示例,并解释你之前可能做过什么,为什么这会导致问题,以及如何通过使用关注点分离原则以及由此获得的一些好处来避免这些问题。

对于这个示例,让我们假设你拥有你的标准默认值。你将要构建什么项目?我们将讨论一个任务列表应用程序。在这个任务列表应用程序中,你正在将其与某种远程 API 同步。可以是服务器,可以是 iCloud,可以是任何东西。我们不在乎。现在,你会做的事情,就像你将要做的最简单、最直接的方法一样,

你将编写某种表示任务的类型。使用该类型,你将说,好的,在 Swift 中,你可能会使其可编码。在 Android 中,对不起,Kotlin,那个东西叫什么语言?不。

在 Kotlin 中,你可能拥有 Kotlin 序列化并使用可序列化标记所有内容,从你的 API 编码和解码它们。然后你可能会直接在你的视图中使用相同的类型。你会说,好的,我有一系列任务。我只是要获取我从 API 获取的这些任务,然后将它们放入列表中。这第一次运行良好。你只需从 API 获取数据即可。它显示在列表中。没问题。

好吧,假设你作为开发人员不控制 API,或者你控制 API,但是你不能,你知道,你是一个移动应用程序开发人员。你不能像使用前端 Web 应用程序那样同时部署它们。现在 API 必须由于某种原因而更改。如果你认为这在现实世界中不会发生,那你就错了,因为这种情况经常发生。我本来想说这个,这个实际上对我来说可能是这里唯一的一件事,因为这种情况经常发生。任何说过,哦,这永远不会发生的人,

生活会很美好的。或者如果某个 API 构建者向你保证它不会改变,那就逃跑吧。所以,是的,这是我在许多不同的工作中看到的事情,就像,好的,文档说这个值永远不会为空。突然之间它为空了。然后你的应用程序抛出错误,崩溃,

静默失败,具体取决于你的语言以及它的类型严格程度,等等。但是,是的,假设 API 必须更改,现在一个字段在以前不可为空时变为可为空。

所以现在,好的,没问题。你必须遍历它,就像,好的,我将这个字段标记为可为空。它现在可以正确解码了。但是现在在我的每个视图中,我都必须处理它可能为空的情况。现在我必须更改我显示此任务的每个视图,以确保此值不为空。或者如果它为空,我正在处理它。你知道,我将其转换为空字符串。我正在做类似的事情。问题是,你现在有了……

完全属于 API 合同的部分现在会影响你构建视图的方式。在本集中我一直在使用的术语的解决方案是关注点分离。现在,关注点分离是一个古老的、古老的、古老的原则。它最早由一位非常多产的计算机科学家 Edgar Jijkstra 于 1974 年提出。我相信我弄错了这个名字。

足够接近了。它在节目说明中,因为我不会尝试发音。我们将链接到关注点分离的维基百科页面。上面有他的名字。不要责怪我们。是的。如果你见过这个名字,你就知道我们在谈论谁。无论如何,他提出的想法是……

代码片段和代码片段有点模糊,但我们稍后再讨论,它实际上只应该关注一件事,那就是关注点分离。如果你有多个关注点,你应该将它们分成多个代码片段。

这可以在几个不同的级别发生。你可以拥有它,你知道,就像,哦,我有几种类型。我有,你知道,不同的类。我有不同的结构。我有不同的东西。或者它可以,比如,升级,你可以谈论它,比如,在流程级别。这就是你拥有单个小型程序的整个 Unix 哲学,它们都能很好地完成某件事。因此,你可以将它们全部连接在一起在命令行上。但总的来说,这个想法是……

某些东西只做一件事,而且它做得很好,而且它不关心其他事情。有些人可能会将其识别为 SOLID 中的 S。这是单一职责,但 Jack Strick 首先想到了这一点。

所以是的,所以我们看到的是我们的代码没有遵循这个原则。它关注两件事。它关注它在服务器上的表示方式。这是你的 API 合同。它关注这些数据将在你的前端、你的视图中如何显示。这实际上已经给我们带来了问题,因为如果其中一件事情发生变化,现在另一件事情也必须发生变化。

所以解决方案是让我们将它们分成两种不同的类型。我现在将用于这些类型的术语并不一定是通用术语,但我将使用术语数据模型。你可能还会听到这些被称为 DTO 或数据传输对象。它们不一定是每种语言中的对象。这就是我使用术语数据模型的原因。

和领域模型。你可能以后听说过领域模型的特定子集。我们会讨论到。但这些是我现在将要使用的术语。数据模型,这是你用来传递数据的。领域模型,这是你在应用程序中使用的版本,因为它特定于你的应用程序的业务逻辑。

到目前为止有什么问题吗?不,不。我的意思是,我同意你到目前为止所说的所有内容。是的。嘿,朋友们,如果你喜欢你在这个播客中听到的内容,并且你想帮助这个播客继续前进并拥有优秀的嘉宾和精彩的对话,我邀请你成为 Patreon 支持者。你可以访问 patreon.com/compileswift,在那里你将获得无广告版本的播客以及其他内容。

好的,让我们从数据模型、DTO 开始。在我看来,这理想情况下应该编码你的 API 合同,不多不少。显然,情况并非总是 100% 如此,但这是理想情况。你真正做的只是说,这就是我与 API 交谈的方式。而且我真的不想比这更复杂。

计算机科学中存在一个名为波斯特尔法则的想法。它也称为稳健性原则,其措辞大致为:发送时要保守,接受时要宽松。也就是说,你知道,

尝试尽可能多地接收内容而不会抛出错误,而不会出现任何问题,并尝试限制你实际发送的内容。接收所有你可以接收的内容而不会出现错误,也不会出现其他问题,并限制你发送的内容。即使你接收的内容不一致,也要保持一致。因此,为此,我认为你希望你的数据模型尽可能地……

尽可能接受。在很多情况下,我认为除非你绝对 100% 确定它绝对永远不会、永远不会、永远不会……

可为空,你应该只将所有字段默认为非空。没关系。继续接受你能接受的任何内容,因为这样,如果某些内容突然开始变为空,你不会突然解码失败,因为你没有预料到这一点。好的。我想插一句。只是为了澄清一下,只是想确保我理解你所说的内容,因为我一直都在向人们灌输……

你知道,允许结果与你预期的结果不同,对吧?其中 null 是一个完美的例子,对吧?仅仅因为有人告诉你,看,这个数据片段将始终为你提供。这是第一个迹象,表明我要编写……

当它不存在时,因为他们越承诺它会存在,我就越告诉自己它有一天不会存在。对。所以,你知道,确保你在这方面保护好自己。对。我认为你应该做的另一件事是接受 API 合同中提供的内容,不要使用任何你正在解码到的类型,这不是你的传输协议所要求的。

可以表示。让我们以 JSON 为例。每个人都知道 JSON。每个人都知道 JSON 中的内容。你拥有对象、数组、数字、字符串等等。JSON 中没有日期。这不是一回事。你可以将其表示为一个数字,即你的 Unix 时间戳。你可以使用一个字符串,例如 ISO 8601 字符串,等等。不要尝试在你的 API 合同中编码……

日期的概念。如果你的系统将向你发送字符串,则将其作为字符串接收。如果它将向你发送字符串,则将其保留为字符串。我知道有些语言,我们又要回到 Swift 了,这是我们的核心业务,有一些东西,哦,好吧,你知道,你可以在你的可编码结构中放入一个日期,并且你可以进行一些设置,以便在运行时为你解码它。不要使用这些。你应该接收一个字符串。如果它是字符串,

稍后我们将确定它是否可以转换为日期。接受你的 API 可以提供的内容。不要接受任何其他内容。我非常同意这一点,因为,好的,我知道那里的人们会说,但是 Peter,你总是说你多么讨厌将字符串用于字符串匹配等事情。是的,这是真的。但这与我们在这里讨论的内容不同,对吧?传入的数据需要尽可能简单。我认为你不会比字符串更简单了。是的。我们还有其他选项即将推出。所以让我们现在讨论这些。

另一方面是你的领域模型。

在你的领域模型中,你可以做所有这些事情。这就是你想要的。这是适合你的应用程序的表示。这是你将在你的应用程序中使用的。这就是你将在你的应用程序中传递数据的方式。所以你可以拥有你想要的东西。你可以拥有非可选值。所以你知道,如果我正在处理它,它不是可选的。它会存在。我们在类型系统中保证了它的存在。你可以拥有这些更复杂的表示,例如日期。你可以说,像,

好的,这是一个真实的日期。它有一个与之关联的时区。我们可以对其进行日期计算。我们可以做任何我们想做的事情。它在那里处理。你可以拥有你的枚举,这样你就不会做 Peter 刚才抨击的字符串类型的事情,你正在比较字符串或你正在比较任何其他东西。你可以在你的应用程序中拥有所有这些好东西,它们不是……

连接到 API。它们不是你 API 合同的一部分。现在,我认为很多人会熟悉并且可能还没有意识到的一种领域模型版本,但是一旦我说出来,就会点击,

最常见的领域模型类型之一是视图模型。因此,在这种情况下,你拥有数据的一个版本,因为它需要在应用程序中表示,并且它以明确的方式设置,以便在此处显示。这就是你的模型,因为它适用于视图模型。名称相当直接。是的。

我认为在许多简单的应用程序中,这可能是你所需要的一切。你需要你的数据模型,你需要你的视图模型。这两件事就是你的连接。我认为我在这里使用术语领域模型的原因是,我认为对于更复杂的应用程序来说,说这些是你的唯一两个模型有点局限性。并且在很多情况下,拥有一个额外的层几乎是有意义的,在那里你拥有你的数据模型,你拥有你的……

内部业务逻辑领域模型,以及你的视图模型,并且你可以在所有之间进行映射,好吧,你可以在领域模型的中心进行处理。因此,你可以从数据模型到领域模型。你可以从领域模型到视图模型。你可以从视图模型到领域模型。你可以从数据到领域,但你永远不会从视图到数据。你总是通过那个中心的领域模型。

我想插一句并指出这一点,因为我仍然遇到一些人,他们会获取传入的数据,将其直接推送到视图中,执行任何操作,然后再次通过数据将其发送出去,这让我很生气。这不是一个好方法,朋友们,对吧?就像我们所说的那些 API 会发生变化一样。好吧,如果数据发生变化,你将进行大量返工。我认为这是一种不好的做法,对吧?

不使用视图模型的中间件层。这只是我的两分钱。所以让我们谈谈实现。你将如何实际做到这一点?你将如何实际维护这两个单独的模型?所以我认为你的应用程序的核心是你有一个……

负责实际与你的 API 通信。一件需要查找的事情可能不是每个人的解决方案,但绝对是一个好的起点,那就是存储库模式的概念。这基本上是一种说法,就像,我有一件事处理与我的数据通信,以及……

我发送到和接收自它的只是我的领域模型。存储库内部本身处理数据模型,并且它引用数据模型,因为它需要与 API 交谈。但在存储库之外,你永远不应该看到该数据模型。此时你只处理领域模型。你处理它的方式是使用数据映射器。

它们是用于说明……的数据映射器……

在你的数据类型和你的领域类型之间进行转换,反之亦然。它们真正存在的目的是处理那里的所有复杂性,例如,好的,我们有一个字符串形式的日期。我们需要它作为实际日期。哦,我们无法解析它。现在我们可以说,这是具体的错误。这是具体的对象。这是此失败的具体原因。因此,所有错误报告的复杂性都在你的数据映射器中。你的数据映射器可以真正地……

做任何它需要做的复杂操作。你的数据映射器可以处理,哦,我们有多个不同版本的 API。如果我们看到这个东西的版本一,那么它……

你知道,ISO 8601 字符串。如果我们看到版本二,它有,你知道,之前没有的时区,等等。所有这些复杂性都进入你的数据映射器类型。这样你就不必将其放在你的领域模型或数据模型中。

你不需要将其放在你的存储库中。一切都集中在一起。这就是将此内容转换为另一内容的内容。休息时间到了。嘿,大家好。我是 Compile Swift 播客的 Peter Whittem。我想告诉你关于 Setapp 的信息。Setapp 是一项服务,每月只需支付 10 美元的订阅费,你就可以访问 200 多个 Mac 应用程序。它现在也可以作为该交易的一部分在 iOS 上使用。

我使用这项服务,因为它有很多我经常使用的真正优秀的一流应用程序。对我来说,作为一名开发人员,能够访问用于 API、项目规划、撰写电子邮件、撰写文档的工具非常宝贵,你还可以获得所有这些东西,包括数据库应用程序,所有这些都在 Setapp 服务上,每月只需 10 美元。你可以根据需要使用任意数量的应用程序。

如果你有兴趣查看此内容,请访问 peterwhitam.com,P-E-T-E-R-W-I-T-H-A-M.com/setapp,S-E-T-A-P-P。你可以在那里看到详细信息。它有一个链接,你可以通过它来使用这项服务,并查看它对你来说如何运作。我强烈推荐给每个 Mac 用户。休息时间结束。

好的,太好了。现在,你到目前为止所说的所有内容,这可能是一集独特的节目,因为我完全同意你。所以把它写在日历上,朋友们。好吗?这种情况不会经常发生。但我认为一个好例子是测试你的代码。就像你说的那样,就像查找错误一样。还有当……

当 API 发生变化时,当你的业务逻辑发生变化时,所有这些关注点分离都是一种很好的方式,可以这么说,太好了,我只重写了我的代码的这一小部分。我没有重写我的应用程序的大规模重构,对吧?但我认为其中一个重要的方面是它确实使它在我看来非常易于测试。嘿,这本身就是一个巨大的好处。所以让我们谈谈这样做的一些好处……

再次抵消,因为我相信有些人会说,哦,但这太费事了。所以让我们谈谈为什么这很重要的好处。由于每个部分都只处理一小部分内容,因此它更容易测试,因为你不需要构建这种完整的管道。例如,我刚刚讨论了这些数据映射器。

所以拥有一个你之前说过的东西,好的,你知道,如果我有这个版本的这个,我需要这个。如果我有这个版本,我需要这个。如果你正在处理的是你的最终视图,那将非常复杂。你将不得不……

向它传递大量内容,并确保你拥有像数据一样的东西。我见过很多情况,人们只是说,哦,我们正在模拟我们的整个网络堆栈,因为你知道,我们正在,我们正在摆脱一切,因为你知道,在最终视图中,我们我们需要能够说出 JSON 是什么。这就像,这是,这是太多了。或者更糟糕的是,人们只是说这太费事了。我们不会这样做。

而有了这个,就像,好的,你有一小部分这个,你可以说,我正在将这个非常特定的数据传递到这里,并且我希望这个非常特定的数据返回。它使测试变得非常容易。它还意味着,正如我们之前所说,你能够处理更改,而无需真正……

让它级联到你的应用程序的其余部分。这就是我们讨论的小更改,例如,你知道,可为空字段或非可为空字段突然变为可为空。

诸如此类的事情。但就像我看到过巨大的迁移由于缺乏关注点分离而失败一样。你知道,在过去的工作中,我们有一个案例,整个应用程序都是基于 gRPC 和协议缓冲区构建的。我不会解释它们是什么,但总的来说,这就是我们与 API 通信的方式,并且……

然后它变成了 GraphQL,我们突然开始使用 GraphQL 了。

现在,问题是我们的所有 gRPC 对象都直接在 UI 中使用。当我们切换到 GraphQL 时这意味着什么?好吧,这意味着我们不仅必须更改我们的网络层,还必须更改我们的每一部分代码,以确保它现在正在处理这个新的 GraphQL。如果我记得没错的话,就像它甚至没有……

一次全部移动。所以它就像,哦,我们有,像,

这边是 Protocol Buffers,那边是 GraphQL,它们之间根本无法通信。这简直是一场噩梦。而这种情况,如果一开始就将所有内容分开,就能省去我们很多麻烦。是的,如果在到达存储库层之后,

你就不必再担心是 Protocol Buffers 还是 GraphQL 了。这将非常棒,尤其是在大型公司中,你可能有不同的团队。你有一个平台团队,你还有专门负责应用程序特定部分的功能团队。为什么你的功能团队需要关心网络上发生了什么?这无关紧要。他们应该能够在不考虑网络的情况下构建这些东西。同样,就团队分离而言,

如果你正在构建这样的东西,并且知道你可以依赖某种内部业务工具,这意味着你作为前端团队、移动应用程序团队或任何团队,都可以开始根据这些内部类型构建你的功能,而无需后端可用。我在许多不同的公司都看到过这种情况,人们会说,好吧……

我们需要构建这个功能,但是我们还不能构建这个功能,因为后端团队还没有完成后端。你知道,当你不想做任何事情时,用这个做借口是很好的,但是你实际上可以构建这些东西。你,没有理由一定要等待后端团队完成这类事情,直到你构建的是数据映射器、存储库端,你可以根据这些内部领域模型构建你的整个功能,然后构建

你只需要后端来进行两者之间的转换。你可以继续你的工作,而无需被其他团队阻塞。我想说,我知道这可能是有争议的,但是,你知道,我认为如果你发现自己说,我不能,让我们以日期为例,好吧,我不能这样做,还不能构建应用程序的这一部分,因为我没有

我需要在此处放置的这个数据,这个日期,以及查看它的外观,这应该是你没有认真思考或做错了的第一个信号,因为……

代码异味的流程等价物是什么?完全正确。你知道,因为我完全同意你。是的。好的。尽早拥有你在某个时刻需要的一切是有好处的,这样你就可以编写代码、测试等等。但是,如果你以某种方式说你依赖于它来构建应用程序的 X 部分,那么

我会说,那么你可能才是问题所在,而不是日期的来源,对吧?我的意思是,我过去在一个公司有过这样的经历,我们等待的后端是一块硬件。我们正在与必须制造和原型化的硬件进行通信,所有这些。就像,如果我们一直坐在那里说,好吧,我们实际上还不能构建任何应用程序,因为我们需要这个硬件。就像,

我们六个月都没有工作。是的,所以,是的,你需要能够处理内部事物,然后能够模拟最后一点。你就像,我知道我需要这个功能。我需要这个数据。然后,就像,你可以构建包含你需要的数据的领域模型并使用它。然后就像,好吧,在某个时候,

可能在后端实际启动和运行之前,你会得到规范文档,然后你可以开始一起构建映射器。你,你知道,你会有你的映射器,你可以构建映射器,你可以说,好吧,这就是我们知道 API 合同将是什么样的。这将与之一起。然后,就像最后一点一样,就像 URL 会话连接一样,就像将其连接到实际网络一样。嗯,

但是是的,因为你可以,你可以有不同级别的。你可以让你的存储库只向你提供最终结果。当我需要模拟存储库时,我通常的做法是,好吧,它就是这样做的,但你也可以模拟存储库之上的网络层,并说,好吧,这个网络层正在向我提供。

数据模型。然后它通过我的存储库,然后通过映射器,然后通过领域模型。但老实说,大多数时候我只是,我只是模拟存储库,然后说,是的,继续返回这些领域模型。我跳过了其他那一点。

所以是的,我想我现在基本上要说这些了。你从这里获得了很多好处。它确实需要前期做一些额外的工作,但我认为它允许你对你试图做的所有事情更加明确。显然,它有很多这些前期的好处。所以我绝对推荐……

一定要查看我们包含的链接,对此进行更深入的阅读,但在下次在你的应用程序中构建这些东西时,真的要开始考虑这一点。它确实使

因此,更容易继续扩展、继续测试、对后端中的意外更改做出反应。你从这里获得了许多好处。所以我绝对建议你看看,看看你可以在哪些方面改进你的应用程序。

是的,我认为,我想在这里指出,我个人认为,最好花时间提前考虑这些事情,避免以后因为没有经历这个过程而承担技术债务。我认为,当你设计你的应用程序时,我的意思是设计,我指的不是 UI 和所有内容。我的意思是,当你构建它时,

把这些放在你的首位,对吧?现在就是这样。如果下周发生变化怎么办?正如我们前面所说,下周如果你们曾经在公司和大型产品或类似事物中与团队合作过,他们改变它时总是会发生。或者六个月后,当他们转向一些新的东西,或者你被收购,它变成其他东西时。

所以现在就计划好,对吧?在技术债务发生之前阻止它。它不会完全解决你所有的问题,但它会将你的一些问题与较小的重构隔离开来。这是一个很好的说法。它将你的问题隔离开来。是的。

当你遇到问题时,你会遇到问题,这是软件开发的本质,你限制了你的影响范围。如果某些东西发生了变化,你真的有这个存储库的防火墙,说它不会传播到此之外,因为……

其他一切,就像它与之隔绝一样。那是你的断点。你不需要因为另一件事改变而重新构建你的整个应用程序。是的,同意。而且,正如我们所知,开发人员,嘿,他们讨厌不得不回去重做事情。他们喜欢做新的和酷的事情。好吧,如果你这样做,猜猜怎么了?你将减少返回次数,并节省在这方面的时间。

好的,杰夫。非常感谢你。各位,我们将在节目说明中添加文章链接。去阅读它,并将其放在你的首位。杰夫,他们在哪里可以找到你?你可以在 Cocotype.com 找到我所做的一切,尽管本周的博客文章实际上并不在那里。Cocotype.com 有一个指向它的链接。是的,Cocotype.com 是杰夫的起点,对吧?

对我来说,起点是 PeterWhitam.com。各位,如果你喜欢在这里听到的内容,对吧,来加入我们的 Dev Club Discord。同样,节目说明中会有链接。我们经常讨论这类事情。我们讨论了许多与开发相关的不同主题。但这些是经常出现的主要领域。而且,你知道,我们经常被问到这些问题。而且……

加入我们的 discord,这些对话不仅会发生在那里,而且你还可以获得所有这些精彩的参考,你可以引起这些问题,是的,你可以引起这些关于隔室化的问题,对吧,嗯,这就是各位,这就是我们为你准备的,我希望这对你们有所帮助,如果你想再进一步,请给我们留下评论,嘿,这是 Patreon 的链接,我们非常感谢,谢谢各位,我们将在下一集中再见