Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 如何建模使用DDD保存图像的操作?_Design Patterns_Domain Driven Design_Aggregateroot - Fatal编程技术网

Design patterns 如何建模使用DDD保存图像的操作?

Design patterns 如何建模使用DDD保存图像的操作?,design-patterns,domain-driven-design,aggregateroot,Design Patterns,Domain Driven Design,Aggregateroot,基本上,用户希望更改其配置文件图片。 web服务器接收到针对/user/35435/profile/picture发布的图像,因此需要保存数据,并更新profile对象的LastModification属性 图像不是本地存储在web服务器中,它们需要上传到其他地方(即:云存储) 目前,每个操作都由命令或查询表示。命令在环境事务(如SQL事务)中运行。映像上载操作不是事务性的,但在出现错误时可以执行补偿操作(即:如果DB操作失败,则删除映像) 在一个简单的实现中,会创建一个同时包含当前日期和图像数

基本上,用户希望更改其配置文件图片。 web服务器接收到针对
/user/35435/profile/picture
发布的图像,因此需要保存数据,并更新profile对象的
LastModification
属性

图像不是本地存储在web服务器中,它们需要上传到其他地方(即:云存储)

目前,每个操作都由命令或查询表示。命令在环境事务(如SQL事务)中运行。映像上载操作不是事务性的,但在出现错误时可以执行补偿操作(即:如果DB操作失败,则删除映像)

在一个简单的实现中,会创建一个同时包含当前日期和图像数据的命令。执行一个命令处理程序,它加载
ProfileAggregate
aggregate和
ProfileAggregate。updateProfilePicture(imageUploader,image,currentDate)
通过
imageUploader
域服务作为参数执行。在方法内部,上传图像并更新配置文件。命令处理程序将更改保存在数据库中并返回

我不喜欢在图像上传过程中进行事务处理。我不喜欢从聚合中执行非域模型操作(如上载图像)(即使聚合在其他地方调用)


这种交互应该像两个以串行方式执行的独立命令那样建模,还是可以将任何东西放在一个聚合中,只要在具体实现中没有依赖关系。

您的命令处理程序可能位于您的体系结构的“应用层”中。因此,考虑到这一点,您将收到一个命令并协调您的域/其他服务以满足它

也就是说,我并不喜欢两个不同的命令实现,因为从客户端的角度来看,它们只执行一个操作。您可以创建一个代理命令(单个命令),并在其处理程序上生成两个命令(一个用于处理聚合,另一个用于处理上载),但这种方法将使您的API/模型在将来变得不那么直观

我也不喜欢将操作的上传部分捆绑在概要聚合中,因为这似乎根本不是它的职责之一

我在这里建议的是以下方法:

  • 配置文件聚合应负责接受图片。因此,它的操作updateProfilePicture将简单地评估图片元数据(也许你有一个规则,图片必须有一定的大小,或者根据某种算法进行验证,以试图找到裸体,这类东西)以及目标配置文件的内部状态,以允许操作发生,并使用LastUpdate属性或其他内容更新其内部状态

  • ImageUploadService将为您提供独立的功能来接收图像并相应地存储它

  • 这两种操作将独立进行,并最终通过消息传递保持一致

因此,您的命令处理程序将:

  • 加载配置文件集合
  • 调用updateProfilePicture(如果达到无效状态,它将中止)。在这里,您可能希望将概要文件聚合保持在PendingUpload状态(如果您希望采用悲观方法进行上载),或者假设上载通常会成功(采用乐观方法),并在失败时采取补偿措施
  • 直接异步调用ImageUploadService(激发并忘记)
  • 在上传过程中提交对概要文件的更改
当ImageUploadService完成接收图像时,它将向配置文件域发送一条消息,报告上载成功/失败。然后:

  • 如果您采取悲观的方法,那么成功将使概要文件聚合脱离其挂起状态
  • 如果你采取乐观的态度,成功就不需要处理
  • 在任何情况下,上传失败都应该通过将配置文件聚合回滚到图片的预更新状态来处理

帮助您的主要问题是,当图像无法上传时,系统应该怎么做。我认为答案是你希望用户收到一个错误,系统(配置文件)应该保持不变

从领域的角度来看,实际的图像上传/存储过程是不相关的。此操作实际上是基础结构的一部分,在将命令发送到域层(配置文件聚合)之前,应由应用程序层进行编排。这样,无论出于何种原因,如果上传失败,将不会发送命令


图像上传可以同步进行,也可以异步进行;这取决于您的平台/编程语言等,与此无关。关键是,只有在图像上载成功后,才能将命令发送到聚合。该命令应该包括ImageStorageId和一些元数据(如文件名、文件大小、imagesize等)。

我目前坚持在运行domain命令之前处理文件上传

除非域模型需要直接处理图像(或其他文件),否则将所有基于文件的操作(包括上载和裁剪)都远离它似乎是合理的。因此,如果您不分析模型中图像中的数据(例如,我不知道,人脸检测?),而只需要一些抽象的配置文件图像,则将元数据对象传递给模型


如果域模型中出现故障,它将发送一个事件,应用程序将处理该事件并执行一些回滚逻辑。

KISS:在加载聚合并发送之前上载映像。只有映像元数据和storageId(不包含实际映像数据)命令用于协调逻辑实现