问题标签 [clean-architecture]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
447 浏览

node.js - 如何在 CouchDB 中实现唯一键约束

我使用 CouchDB,我希望我的所有用户都拥有独特的电子邮件。当我尝试复制电子邮件时,我希望数据库返回状态 400(错误请求)。

但是由于没有办法在 CouchDB 中定义约束,我应该自己实现它,我的问题是:

这条规则应该站在我的应用程序的哪一层?

(1)领域对象层
这个层 我还真不知道怎么实现

(2) 交互层
这个约束可以在交互器中实现,因为这里有业务规则所在的地方。但是,如果单个文档有多个规则,则可能会增加不必要的复杂性...

(3) 数据库网关层
约束也可以在数据库网关层实现。通常我们会为每个特定实体设置一个网关。但这是否意味着外部服务适配器包含一些业务逻辑?

0 投票
2 回答
3021 浏览

android - 在干净的 MVP 中,谁应该处理组合交互器?

我已经看到了 MVP 架构的好例子(这里这里)。两者都只提供简单的交互器,但我想知道如何处理更复杂的用例,包括在其他用例中重复的步骤。

例如,我的 API 需要令牌来验证任何调用。我创建了一个交互器来获取该令牌(GetToken)。我想获取用户的最后一次登录日期 ( ),然后获取从该日期到现在 ( )GetLastLoginDate之间发生的更改列表。GetVersionChanges

那些交互者应该被锁在哪里?我想将它们分开,因为其中一些在代码的其他部分中被重用。我想出了两个解决方案。

  1. Presenter 应该链接所有的交互者。只要用例不复杂且没有太多先决条件,此解决方案就可以工作。在我看来,这不是正确的地方,因为它让主持人承担了另一项责任。

  2. Interactor 可以使用许多存储库(那时没有破坏干净的架构规则)。为什么不在TokenRepository其他交互器中使用?因为获取令牌比仅仅访问存储库要复杂得多。在其他交互器中重复这些步骤不会重用已经存在的代码。

这两种解决方案都有其缺陷,并且违反了基本原则(DRY,单一责任原则)。

0 投票
2 回答
712 浏览

node.js - 如何实现noSQL数据库抽象?

我使用 CouchDB,这是一个面向文档的数据库,将数据存储为 JSON 文档。我在后端使用 Javascript,所以我可以直接存储 JS 对象。目前,我在存储在 CouchDB 中的模型和我的域层之间有直接映射。我认为这不是一件好事,因为我完全依赖这个数据库。

例子

我有 2 个实体用户项目。一个用户可以有多个项目,这些模型在数据库中表示为单独的文档:

用户文档

项目文档
关系由属性user_id引用。

我的问题是:
我应该在层之间保持这种方便的映射,还是应该创建一个抽象层,将模型从数据库转换为域对象?

更方便的用户域对象示例:

注意:我想阅读 Eric Evans 的《领域驱动设计》一书。也许它可以帮助我了解如何管理此类模型抽象。

0 投票
2 回答
2572 浏览

domain-driven-design - 域实体应该调用存储库吗?

我正在设计一个运输应用程序并尝试使用 Clean Architecture 和 DDD。在领域层的核心深处,我们有许多可配置的业务规则。例如,有用于确定货物的最佳承运人、确定运输方式、确定付款类型等的业务规则。每个业务规则都从数据库中选择数据,因此我计划使用 BizRule 存储库。问题是根据我对 DDD 原则的理解,域实体(例如 Shipment)不应该调用存储库(例如 BizRuleRepository)。用例层应该是调用存储库的层。如果我采用这种方法,那么我将不得不将许多复杂的业务规则移至用例层,我​​不确定这是否是最好的方法。在这种情况下,进行异常并让域实体调用存储库是否有意义?先感谢您。

0 投票
1 回答
2187 浏览

android - Android 应用清洁架构:数据层应该有自己的模型类吗?

在开发 Android 应用程序并尝试遵循干净的架构指南时,最好的方法是什么(但不是非常严格——因为这对于小型项目来说可能是矫枉过正)。

就我而言,我不确定哪种方法对于 数据层是最好的(如果有最好的),以及数据层是否应该在其自己的模型类上运行,或者它是否可以直接在域层模型上运行。

此外,如果数据层应该在其自己的模型类上运行,数据源是否应该喜欢DBAPI拥有自己的模型(例如API使用RetrofitGson带有Gson注释的模型类),然后映射到数据层模型,或者数据层模型本身应该是DBand返回的模型API(这意味着必须对数据层模型进行注释,以便在andGson的情况下能够解析它)。RetrofitGson

本项目就是这种情况: https ://github.com/android10/Android-CleanArchitecture/blob/master/data/src/main/java/com/fernandocejas/android10/sample/data/entity/UserEntity.java

以下图片应阐明我的意思的 3 种方法:

图 1DBAPI返回特定的模型类。在的情况下,API它可能看起来像(使用Retrofitand Gson):

然后这些由本地/远程数据源映射到Article模型(由域层使用)。因此,存储库在域层模型上运行并且打破了界限,对吗?那是方法1。 图片1

图 2DBAPI仍然返回特定的模型类。在的情况下,API它可能看起来像(使用Retrofitand Gson):

但是,这些模型随后会映射到数据ArticleEntity层操作的数据层模型 ( )。当响应领域层时,repository将这些映射ArticleEntity到领域层模型Article。这不会打破边界(右),但它需要在数据层中进行一些额外的映射。这是方法2。

在此处输入图像描述

图 3中,DB并且API已经返回了数据层模型ArticleEntity。因此,这个模型类必须包含解析 API 请求所需的所有注解(带有Gson):

如果数据库还需要某种注释,那么这些注释也必须添加到此类中(对吗?)。我能想到的这种方法的一个优点是模型类更少(因为 DB 和 API 直接映射到数据层模型)。但是,这不会用来自所有不同数据源(DB、API)的注释/属性来破坏数据层模型类吗?是否违反了从存储库中抽象数据源的全部要点,因为数据层模型依赖于特定的数据源实现(例如,使用 Gson 解析具有确切 API 响应名称的 API 请求)。所以这是方法3。

在此处输入图像描述

我的问题是:这 3 种方法中哪一种是最灵活和面向未来的方法?

0 投票
2 回答
3316 浏览

domain-driven-design - 干净架构中的用例交互器应该有多大或多小?

我试图弄清楚如何最好地使用 Clean Architecture 和 DDD 来定义用例。假设我有一个应用程序来处理交货的拣货、包装和运输。这是流程:

  1. 用户输入交货以在屏幕上填充运输信息
  2. 用户选择订单项并单击按钮选择
  3. 用户输入包装信息(例如重量和尺寸)并单击按钮进行包装。
  4. 用户点击发货按钮调用外部系统获取发货标签

以下是我正在考虑定义我的用例交互器的选项:

  1. 创建 4 个 Interactor 类,为上面列出的每个步骤创建一个
  2. 创建 1 个带有 4 个方法的 Interactor 类来处理上面列出的步骤
  3. 创建 3 个交互器类

    一个。交互者 1 将处理 Enter Delivery 和 Pick

    湾。交互器 2 将处理包装

    C。交互器 3 将处理运输

先感谢您!

0 投票
1 回答
1601 浏览

android - 干净的架构 - 进行数据模型映射的正确方法是什么?

我已经阅读了这篇关于在 android 中使用干净的架构和 MVP 进行数据建模的令人印象深刻的文章

现在我想重构我在我的域中拥有的一些现有模型,以便它们不包含可打包代码(android 代码)并且经过简化以在特定视图中工作。您知道有时我们必须更改模型以使其在视图中工作,例如为了在 RecyclerView 中获取选定位置,我们将向模型添加一个名为“selectedPosition”的字段。很多时候我们需要更改模型,然后我们最终得到的模型不纯并且有点难以维护。

具体来说,我有我正在使用的 3 个支付系统的 3 个模型数据。3 个模型中的所有字段都不同。他们有不同的字段名称。有人可以向我展示一个用于使所有 3 个模型都使用通用模型的架构示例吗?

0 投票
2 回答
15926 浏览

android - 清洁架构、用例和实体

好的,所以我刚刚开始了一个新的 Android 项目,并想尝试实现 Bob 叔叔的 Clean Architecture。我在使用 RxJava 以及来自 GitHub 示例和样板以及 Fernando Cerjas 的博客(如本文)的东西有一个很好的开始,但对于如何实现一些用例仍有一些疑问。


TL;博士

一个实体是否应该具有另一个实体的字段(在我的示例中,User有一个List<Messages>字段)?

或者 Presenter 应该结合 UseCases 来构建一个映射到多个实体上的 ViewModel(那么你如何编写映射器?)?

或者,Presenter 是否应该有一个与每个 UseCase/Entity 关联的 ViewModel,并创建某种“等待所有数据到 onNext”来为每个 ViewModel 调用 view.show()?


基本上,UseCases 应该只返回实体吗?实体可以由其他实体组成(如在类的字段中)吗?实体只是愚蠢的数据模型 POJO 吗?你如何表示“加入 SQL”查询?

例如,让我们以一个简单的用户/消息应用程序为例。我想实现两个视图:UserListUserDetails

  • UserList显示列表Users
  • UserDetails显示用户的信息及其最新消息。

UserList非常简单,我可以看到如何编写相关的 UseCase 和层(代码如下)。

我的问题是UserDetails屏幕。

GetUserInfoUseCase如果我希望同时在视图中传递所有数据(例如构建由 User 类和字段 List 组成的 ViewModel),我应该如何编写我的代码?的返回值应该是GetUserInfoUseCase多少?我应该在我的演示者中编写 aObservable<User> GetUserInfoUseCase和 aObservable<List<Message>> GetUserLatestMessages并以某种方式合并它们吗?如果是,我该如何管理这个,因为我的 Presenter 中没有 Observables(我只传递一个 Observer 作为我的 UseCases 参数)?

用户实体

消息实体

获取用户用例

用户演示者

UseCaseObservableWithParameter

用例

0 投票
1 回答
1191 浏览

domain-driven-design - 如何在 DDD 中处理货币转换?

简短版本: 对于需要访问数据库中的货币兑换率的值对象,您认为什么是最佳选择?前任:

Invoice.Amount = Invoice.Amount.toCurrency('CAD')

长版: 我有一个名为的值对象InvoiceAmount,它有一个方法,toCurrency将发票金额转换为指定的货币。我想重用这个货币转换逻辑,因为我知道我将在其他有界上下文(例如,等)中需要SalesOrderAmountFreightCost。我的第一个想法是在 SharedKernel 中创建一个对象,Money然后拥有并继承自. 将在课堂上实现,所以它只在一个地方。这对我来说听起来不错,但也许有更好的方法。现在我遇到的问题是,在我的系统中,货币兑换率存储在数据库中,因此我需要一个存储库来访问兑换率以便实施SalesOrderAmountFreightCostInvoiceAmountMoneytoCurrencyMoneyMoneytoCurrency. 我很确定 DDD 说不要在实体或值对象中调用存储库,所以我正在努力弄清楚如何实现这一点。我正在考虑使用域服务来实际进行货币转换,并且Money只会调用域服务,但是,我不确定 DDD 是否也认为这是一个不错的选择。也许我需要将域服务注入到每个聚合根 (和) 中SalesOrder,这样我就可以将它注入到每个 Money 值对象中,这样它就可以依次进行货币转换。你怎么看?先感谢您。InvoiceShipment

0 投票
1 回答
1010 浏览

domain-driven-design - 如何在 DDD w/Clean Architecture 中处理具有太多依赖参数的 UseCase Interactor 构造函数?

使用带有 Clean Architecture 的 DDD,我首先实例化所有依赖项(例如存储库和服务)并将它们注入到我的用例中。随着时间的推移,我注意到我对每个 UseCase 的依赖项列表随着时间的推移变得非常大。例如,我的 UseCase 使用 3 个聚合根,所以我有 3 个存储库。没那么糟糕。但是,随着我添加更多功能,我发现自己添加了域服务或更多存储库,并且还必须将它们注入到 UseCase 构造函数中。在用例交互器中可以有 10 多个参数吗?我一直认为超过 2-3 个参数是一种代码味道。有没有更好的方法来处理这个?先感谢您。