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
Oop 实现类似的用例看起来像是代码复制_Oop_Design Patterns - Fatal编程技术网

Oop 实现类似的用例看起来像是代码复制

Oop 实现类似的用例看起来像是代码复制,oop,design-patterns,Oop,Design Patterns,我有以下情况。用户可以将多个对象类型(交易、发票等)导出到外部会计系统。 导出算法包含以下步骤: 通过某些筛选器获取对象 将对象逐个导出到记帐系统(每个对象类型的web服务方法) 注册已导出给定文档的事实,以便不再导出该文档 为用户准备摘要(导出文档的数量、错误消息等) 所有对象类型的算法都是相同的,但必须处理一些重要的差异: 不同类型 不同的目标web服务方法,不同的对象到DTO映射 每个对象类型有不同的过滤器 我考虑了一些解决方案: 不要将导出算法视为代码复制,而应按对象类型实现算

我有以下情况。用户可以将多个对象类型(交易、发票等)导出到外部会计系统。 导出算法包含以下步骤:

  • 通过某些筛选器获取对象
  • 将对象逐个导出到记帐系统(每个对象类型的web服务方法)
  • 注册已导出给定文档的事实,以便不再导出该文档
  • 为用户准备摘要(导出文档的数量、错误消息等)
所有对象类型的算法都是相同的,但必须处理一些重要的差异:

  • 不同类型
  • 不同的目标web服务方法,不同的对象到DTO映射
  • 每个对象类型有不同的过滤器
我考虑了一些解决方案:

  • 不要将导出算法视为代码复制,而应按对象类型实现算法。将任何数据导出到任何外部系统都可以用这样的算法来描述——这是否意味着我们应该始终有一个通用类将任何数据导出到任何地方?:)
  • 将差异转移到策略(一个策略接口为所有差异创建抽象)-我甚至实现了它
  • 使用泛型-不幸的是,我用PHP编写代码,这是不可能的
问题:

为每个对象类型创建单独的导出算法是否是代码复制

也许所有这些都应该被视为单独的用例

如果是复制,那么我应该考虑避免哪些技术?

我的第一个实现的描述:

在第一种方法中,我定义了一个可导出的抽象,但对此我并不满意。每个对象都有完全不同的负载。 一个可导出的接口只定义了一个方法getId,它被用来注册导出的对象(由于这个方法不再导出)。
为此,抽象很好,但问题转移到了exportService,它必须检查具体实例以选择DTO映射器和端点。因此,exportService已经崩溃。

您上面描述的所有内容都不是特定于领域的逻辑(事实上,您在问题中甚至没有提到问题领域),因此我认为它不属于领域驱动设计的范畴。因为它不是特定领域的逻辑,所以我不会太担心代码重复,特别是考虑到解决方案似乎并不明显


保持简单,只需分别写出每个用例即可。如果您发现有一些通用代码很容易重构,请在一切顺利运行后再进行重构。不要想得太多,也不要在明显必要之前添加模式。

这是一个很好的问题。您是否考虑了用例之间的«包含»和«扩展»关系?他们可能会在这里帮忙。另外,一些模式(如框架、可扩展性或模板方法)也可以替代您的实现方法。您通常希望将差异转移到策略,然后根据API的设计方式将策略选择隐藏在外观/工厂后面。例如,客户机可能只执行
exportService.export(listOfExportable)
,但在内部,根据
Exportable
的类型,将选择一个web服务端点以及一个dto汇编程序。导出服务可以从外部进行配置,以避免违反开放-关闭原则。您还可以将策略选择放在exportable上。让exportable指定策略的好处是可以避免在导出服务中使用服务定位器模式。exportService只需在
Exportable
上加倍发送即可收集信息。同时,还有一个缺点,因为基础设施问题可能会在不应该泄漏的层中泄漏。这与“我应该在实体中放置ORM注释还是应该使用外部XML文件?”类似。模板方法是一种听起来可能适用于这里的模式@plalx我已经添加了我的第一个方法的描述,创建了一个抽象“可导出”以及它失败的原因。回到你的评论。您的意思是将对象包装到某个具体的可导出实现中,其中Exportable只有导出方法,并且所有差异都隐藏在那里?它可能是其主域的子域。“注册给定文档已导出的事实,这样它就不会再次导出”是域逻辑。