问题标签 [hexagonal-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.
web-services - 设计一个依赖 SOAP API 的服务,它改变了很多
我正在重构一个依赖于 SOAP 服务的服务。不幸的是,SOAP 服务会定期更改。我的服务使用从 SOAP 的 wsdl 文档生成的类。没有任何层可以将 SOAP 服务中定义的实体与我的逻辑分开。换句话说,SOAP 服务泄漏到我的内部,并且它的更改会导致问题。
我想解决这个问题。我正在考虑一种方法,在该方法中,我围绕生成的 SOAP 客户端创建包装器,这将符合我定义的接口。包装器将负责:
- 将我的界面转换为/从我的界面转换为来自 SOAP 服务的内容以及代理需要的内容
- 使用包装生成的客户端调用服务
这样,我将限制 SOAP 服务中更改的影响,以便只有包装器受到影响。
我认为这就是它应该根据“端口和适配器”架构工作的方式。这种方法正确吗?我可以做得更好吗?
jpa - Jpa 实体作为域模型
根据为 DDD 或六边形架构记录的推荐实践 - 域模型应该与与实际使用的技术(表/列名称、连接等、JPA 注释)更相关的数据模型表示分离。这里的一个实际问题是——你如何在这个模型中做乐观版本控制之类的事情?假设您有一个域服务可以读取-->更新-->保存在域模型上。现在 JPA 实体可能有一个无法向上传递的版本列。因此,当保存调用到达存储库并且存储库基本上再次进行(模型->实体)转换和读取+更新时,它将无法判断最初读取的是哪个版本的实体。
次要问题是对此的性能考虑,涉及此处的一些额外阅读
domain-driven-design - 需要关于域模型中的抽象和更新过程的意见
我有一个Agenda
持有 many Card
,并且 aCard
有 multipleDetailItem
持有一个像Email
,Phone
和 aLabel
所以,我可以这样做:
按照规则,只能有一个具有“x@yz”值DetailItem
的Email
实例,因此如果您尝试使用该数据添加一个新项目,它将引发异常。
在我尝试更新DetailItem
. 我找不到让我觉得舒服的方法。
我试着从商业模式而不是实现细节的角度来思考,但我不能长时间搁置它们,它们进入了我喜欢或不喜欢的领域。
问题是我将拥有一个 REST 接口,并且我有两种做事方式。
/cards/<cardId>
使用新detailItems' array, fetch the
卡发送一个by ID, create a new
PUTwith the new data provided in the PUT, and sync the current
。- 将 PUT 发送到 /cards//items/,获取
Card
,找到DetailItem
,并以与选项 1 中相同的方式更新它
如果我选择选项 1,我必须DetailItem
从当前Card
中删除所有新选项中不存在的内容。这导致一些由 ORM 生成的 INSERT 查询和一些 DELETES。根本没有更新。
如果我选择选项 2,我将有许多 PUT 来更改多个项目,这根本不具备性能,它会导致我向其中引入一个 ID 字段,DetailItem
以便我可以识别它们,这引入了一些不属于领域!。
我发现的唯一选择是使用选项 1,并发送如下请求:
所以我可以做这样的事情:
但是,我不知道,也许我有一个错误的抽象有人可以帮忙吗?提前致谢!
events - DDD 中的应用程序事件?
这个问题类似于:DDD 中是否存在应用程序事件术语?,但我不知道如何将那里给出的解释应用于我的具体问题。
我有一个SearchFilmUseCase
事件,我想在FilmSearchedEvent
它完成执行后引发一个事件。目前,应用层正在引发事件。我可以从域中引发此事件的唯一方式是在FilmRepository
. 但是,存储库只是一个接口,所以我不能在那里引发任何事件。
我认为在应用层提出事件是不正确的。我该如何处理这种情况?
php - Laravel 找不到位于其他文件夹中的控制器
我正在尝试在 laravel 中实现一个干净的架构,因此我将自己的代码移动到一个src
文件夹中。
我的控制器位于src\notebook\infrastructure
但当我以routes\web.php
这种方式调用它时:
我收到了这个错误:
我还更改了类中的命名空间值RouteServiceProvider
:
至
这是我的笔记本控制器类:
我的 laravel 和 php 版本composer.json
是:
我觉得我错过了一些愚蠢的东西,但不知道是什么。
android - 从数据库调用覆盖确认对话框
背景
我将我的应用程序设置为六边形架构,将 UI(应用程序)、域和数据库(房间)作为单独的模块。按下 UI 中的按钮后,用户输入数据将保存在房间数据库中。如果 Room 数据库抛出一个SQLiteConstraintException
键已经存在于数据库中的含义,我想查询用户是否要覆盖数据。
我的想法
我是 android/kotlin 开发的新手,但我想这是如何工作的,我会有一个触发 UI AlertDialog 的事件。我将在 DB 模块中引发此事件,如果接受警报对话框,则回调将在我的 Room DAO 中运行 save 方法,这将覆盖数据。
问题
- 我试图在 Kotlin 中找到一些有关事件的文档,但结果是空的。也许我没有使用正确的术语,但“事件”在 Kotlin 中似乎并不是一个公认的东西。
- DB 模块看不到 UI 模块,因此无法直接从 DB 创建对话框。这就是为什么我想首先使用一个事件。
- 因为 Room 是异步的,所以我在
Dispatchers.IO
协程中运行 save 方法,据我所知,不可能在 IO 协程中创建 UI 片段(如对话框)。到目前为止,我已经通过使用绕过了这个问题,this@MyActivity.runOnUiThread
但这感觉非常hacky。
我试过的
所以这是我第一次尝试的hackjob,它确实有效,但我对此一点也不满意。此代码在我的视图模型中的一个方法中,当按下保存按钮时调用该方法。
data.save()
如果 Dao 引发 a SQLiteConstraintException
,则返回 false,否则返回 true。该force
参数确定是否使用onConflict = ABORT
或保存数据onClonflict = REPLACE
。基本上如果force
为真,它将覆盖预先存在的键,如果为假,它会抛出 SQL 错误。保存失败时,将创建一个对话框并提供一个回调,该回调通过强制覆盖重新保存。
我更喜欢在 Kotlin 中使用事件或类似的东西来清理逻辑。
design-patterns - 端口和适配器是否应该抽象出 HTTP 堆栈?
在考虑端口和适配器架构时,我担心过度设计我的代码。
系统与外界联系的两个非常常见的例子是我的HTTP堆栈和本地文件系统。当应用程序与外界联系时,这些情况很明显,并且测试将需要一定程度的控制和/或模拟。
我的第一个想法是:“也许我应该有一个中央服务或单例,并确保任何 HTTP 调用都通过它”
对于测试来说,这将是惊人的,因为如果在没有开发人员模拟或至少明确的音乐会的情况下完成对外界的意外调用,我可以强制任何测试崩溃。这也标准化了模拟 HTTP 调用的单一方式。
另一方面,感觉就像我在重新发明轮子。我是一名 Javascript 开发人员,本机库不太好。大多数人使用第三方库,它将作为依赖项传播到整个项目中。
我目前的方法是重新发明轮子。我确实创建了抽象层(一个服务单例),但使用第三方库使其保持轻便。目标是尝试使用薄的自制外观“遏制”第 3 方库代码在项目中的传播。显然,范围更大的东西是个例外。例如,抽象出数据库访问往往会带来更多的痛苦而不是荣耀。
HTTP和本地文件系统访问的自制抽象是端口/适配器的明显示例还是只是过度工程?
architecture - DDD Hexagon - 在任何情况下,域层都应该与基础设施(DAL)层对话吗?
据我了解,六边形架构的关键规则之一是域层如何与除与它一起工作的应用程序层之外的所有事物隔离(域层完全没有依赖关系,因为它位于核心中):
那么我的问题是,域层是否做过任何工作或对数据持久性有任何了解?假设我们有一些业务逻辑依赖于被检索然后持久化的数据,它应该总是由应用层来编排吗?
加载业务逻辑运行所需的一切 -> 告诉领域层运行所有业务逻辑 -> 提取业务逻辑的结果并告诉基础设施层持久化它们 ->
从这个意义上说,应用层不是总是需要跟踪领域层计算的任何结果,因此总是会实现某种 UnitOfWork 模式来跟踪这些结果吗?
域层会与存储库或存储库的接口一起使用吗?有一些消息来源似乎表明这很好,从我的角度来看,这与图表完全矛盾。
flutter - 使用 Future 函数如何正确处理泛型参数?
我们正在Flutter应用程序中实现六边形架构。对于身份验证,我们创建了一个接口,稍后将由身份验证存储库继承。
两个函数使用通用参数:一个用于社交注册,可以根据身份验证服务(在我们的例子中为 Amplify Cognito)进行更改,另一个接收可以更改的用户属性(同样,根据服务)。
好吧,在存储库中覆盖它们不是问题,但是我在代码级别遇到了一个烦人的错误:
如您所见,*上的类型不同(我无法理解,因为它表示C++上的指针):
The argument type 'AuthProvider' can't be assigned to the parameter type 'AuthProvider*'.dartargument_type_not_assignable.
在这种情况下,此错误带有:
在其他情况下,我们得到:
A value of type 'List<AuthUserAttribute*>*' can't be assigned to a variable of type 'List<AuthUserAttribute>'. Try changing the type of the variable, or casting the right-hand type to 'List<AuthUserAttribute>'.dartinvalid_assignment
。
代码是:
这两种情况的共同点是我定义这些函数的泛型类型。
这个问题只发生在我使用泛型时,在其他情况下不会;如果我们想更改为Firebase提供程序,它会影响原因,我想更改社交身份验证提供程序类型。
我该如何解决这个不匹配的问题?
非常感谢。
typescript - Typescript - Clean 架构中域对象和 DTO 的接口或类?
我对 Typescript 没有太多经验,也没有用它实现架构模式,但我们正在一个项目中工作,我们想使用 Clean Architecture,但我对使用class
或interface
声明 DTO 和域对象有疑问。
我的假设是,Domain Objects
拥有它是一个好主意,class
因为它们可以在其中包含业务逻辑。例子:
但是对于DTO
,因为他们不应该有任何逻辑,我正在使用interface
:
我对吗?