【问题标题】:Can a DTO reference VO of the domain model?DTO 可以参考域模型的 VO 吗?
【发布时间】:2019-08-06 10:42:43
【问题描述】:

问题

数据传输对象 (DTO) 能否引用域模型的值对象 (VO)?

上下文

在我的域中,我有一个从集合中导入聚合的导入器。该集合由进口商所依赖的收集器构建的 DTO 组成。由于导入器和收集器都是我的域的服务(接口),DTO 可以引用域值对象,还是我应该坚持使用原语并仅在处理集合(聚合的构建)时将它们转换为值对象?

收集器实现,其中构建了由域模型中的值对象构成的 DTO

<?php
/**
 * i-MSCP Patcher plugin
 *
 * @author        Laurent Declercq <l.declercq@nuxwin.com>
 * @copyright (C) 2019 Laurent Declercq <l.declercq@nuxwin.com>
 * @license       i-MSCP License <https://www.i-mscp.net/license-agreement.html>
 */

/**
 * @noinspection
 * PhpUnhandledExceptionInspection
 * PhpDocMissingThrowsInspection
 */

declare(strict_types=1);

namespace iMSCP\Plugin\Patcher\Infrastructure\Domain\Service\Component\Importer;

use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentBuild;
use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentName;
use iMSCP\Plugin\Patcher\Domain\Model\Component\ComponentVersion;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\ComponentCollector;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\DTO\ComponentDTO;
use iMSCP\Plugin\Patcher\Domain\Service\Component\Importer\DTO\ComponentDTOCollection;
use iMSCP_Config_Handler_File as MergedConfig;
use iMSCP_Plugin_Manager as PluginManager;
use RuntimeException;
use Throwable;

/**
 * Class DefaultComponentCollector
 * @package iMSCP\Plugin\Patcher\Infrastructure\Domain\Service\Component\Importer
 */
class DefaultComponentCollector implements ComponentCollector
{
    /**
     * @var MergedConfig
     */
    private $mergedConfig;

    /**
     * @var PluginManager
     */
    private $pluginManager;

    /**
     * DefaultComponentCollector constructor.
     *
     * @param MergedConfig $mergedConfig
     * @param PluginManager $pluginManager
     */
    public function __construct(
        MergedConfig $mergedConfig, PluginManager $pluginManager
    )
    {
        $this->mergedConfig = $mergedConfig;
        $this->pluginManager = $pluginManager;
    }

    /**
     * @inheritDoc
     */
    public function collect(ComponentDTOCollection $collection): void
    {
        try {
            // Core
            $collection->add(new ComponentDTO(
                ComponentName::fromString('core'),
                ComponentVersion::fromString($this->mergedConfig['Version']),
                ComponentBuild::fromString($this->mergedConfig['Build'])
            ));

            // Plugins
            $this->collectComponentsFromCorePluginManager($collection);
        } catch (Throwable $e) {
            throw new RuntimeException(sprintf(
                "Couldn't collect list of components: %s", $e->getMessage()
            ), $e->getCode(), $e);
        }
    }

    /**
     * Collects components from the i-MSCP core plugin manager.
     *
     * @param ComponentDTOCollection $collection
     * @return void
     */
    private function collectComponentsFromCorePluginManager(
        ComponentDTOCollection $collection
    ): void
    {
        $pluginList = $this->pluginManager->pluginGetList('all', false);

        foreach ($pluginList as $pluginName) {
            $pluginInfo = $this->pluginManager
                ->pluginGetInfo($pluginName)
                ->toArray();

            $componentDTO = new ComponentDTO(
                ComponentName::fromString($pluginInfo['name']),
                ComponentVersion::fromString($pluginInfo['version']),
                ComponentBuild::fromString((string)$pluginInfo['build'])
            );

            $collection->add($componentDTO);
        }
    }
}

【问题讨论】:

    标签: collections domain-driven-design dto value-objects


    【解决方案1】:

    数据传输对象 (DTO) 能否引用域模型的值对象 (VO)?

    是的,但你要非常小心这样做。

    data transfer object 的核心是消息。为了使消息达到其目的,发送者和接收者都必须对其语义有兼容的理解。对 DTO 架构进行不兼容的更改需要对接收方进行相应的更改。

    在域模型中,值对象不是消息。它是结构化信息,纯粹是当前模型的实现细节。如果我们想部署一个新版本的模型,它使用完全不同的值排列方式或其底层数据结构,那么我们可以。

    因此,拥有一个 DTO(它应该是稳定的)依赖于一个值对象(它不承诺是稳定的)正在为未来的问题创造机会。

    如果你的价值观词汇稳定,那么风险就会降低。

    【讨论】:

      猜你喜欢
      • 2014-09-17
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多