【问题标题】:How to define an entity with translations using DDD如何使用 DDD 定义带有翻译的实体
【发布时间】:2017-11-28 17:24:56
【问题描述】:

我有一个使用领域驱动设计的小型应用程序,现在我想要一个带有翻译的实体。

我在互联网上读到,领域驱动设计的最佳实践是将翻译与模型分开,但我不知道该怎么做。

这是我所拥有的示例:

@Entity
class Product {
    @Id
    private String id;
    private String name;
    private String description;
    private BigDecimal price;
    private BigDecimal originalPrice;

    ...
}

@Service
class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public List<Product> getAll() {
        return productRepository.findAll();
    }

    public List<Product> getById(String id) {
        return productRepository.findById(id);
    }

    public List<Product> create(ProductDto productDto) {
        Product product = new Product(
            productDto.getName(),
            productDto.getDescription(),
            productDto.getPrice(),
            productDto.getOriginalPrice()
        );
        return productRepository.save(product);
    }
}

那么我的问题是:

假设我收到了产品 DTO 中的翻译,我想知道如何去做。

感谢并感谢您的帮助。

【问题讨论】:

  • 好吧,如果翻译是领域的核心,我认为翻译很可能成为模型的一部分。在我们构建的系统中,每个描述性字符串最终都包裹在 TranslatedText VO 中。

标签: spring-boot domain-driven-design ddd-repositories ddd-service


【解决方案1】:

我建议您将域模型与数据模型区分开来。虽然在您的领域模型中,您真的不会关心任何翻译,并且它看起来就像您建议的那样,但您的数据模型可能看起来不同:

@Entity
class Product {
    @Id
    private String id;
    private BigDecimal price;
    private BigDecimal originalPrice;
    private List<ProductTranslation> translations;

    ...
}

@Entity
class ProductTranslation{
    @Id
    private String id;
    private String name;
    private String description;
    private Int languageId;

    ...
}

然后在您的存储库中,您将从您的域模型映射到您的数据模型,同时您将从某些应用程序设置中获取languageId

【讨论】:

  • 非常感谢这个例子。你如何做到这一点意味着与模型分离?谢谢
  • 是的,您的域模型和以前一样,数据模型仅用于持久化。
【解决方案2】:

这不是您的核心领域真正感兴趣的东西,您应该需要对其进行建模。您可能会有一些翻译子域,您对这些东西感兴趣,但该设计将专注于将键/语言对映射到翻译。

您的核心域将为您的位置使用某种默认语言,这将是核心域中众所周知且必需的条目。例如,您的Product 可能有ProductID(或SKU 等)以及Description。该描述将使用默认语言。

您的翻译将作为更多的基础设施服务在集成层上,并且如果有可用的描述,将提供翻译的描述;否则为您的域中需要的默认值。

更新:

我给出的另一个答案DDD: DTO usage with different logic

例如(大致):

public Translation 
{
    string Locale { get; set; }
    string Value { get; set; }
}

public interface ILocalisationQuery
{
    Translation For(string locale, string key);
    IEnumerable<Translation> For(string key);
}

public class LocalisationQuery : ILocalisationQuery
{
    public Translation For(string locale, string key)
    {
        // lookup from localisation data store
    }

    public IEnumerable<Translation> For(string key)
    {
        // lookup from localisation data store
    }
}

您将实施对您有意义且适用于您的用例的策略。假设您想获取 spoon 产品的 Fench 描述,并且您使用 product-spoon 作为密钥的约定:localisation.For('fr', 'product-spoon');

对于我的 JavaScript 前端,我使用 i18next

【讨论】:

  • 您好埃本,感谢您的回答。你能给我一个例子吗?谢谢
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多