gpt4 book ai didi

domain-driven-design - 如何创建多语言领域模型

转载 作者:行者123 更新时间:2023-12-04 14:14:58 26 4
gpt4 key购买 nike

我正在使用域驱动设计,并且对我的域模型有一个非常清晰的了解。它包含超过 120 个类,并且非常稳定。我们将在 .NET 4 和 C# 中实现它。问题是,我们需要模型是多语言的;一些属性需要以多种语言存储。例如,Person 类有一个 string 类型的 Position 属性。它应该以英语(例如“Librarian”)和西类牙语(例如“Bibliotecario”)存储一个值。此属性的 getter 应根据某些语言参数返回英语或西类牙语版本。

这里开始我的问题。我不确定如何参数化它。我已经探索了两种主要的方法:

  • 使用属性集合。位置不会是 string而是一个 Dictionary<Language, string> ,这将让客户通过语言检索此人的位置。
  • 保持简单的标量属性,但让它们根据全局已知的“当前语言”设置返回(或设置)一种语言或另一种语言的值。客户端代码将设置工作语言,然后所有对象将设置并获取该语言的值。

  • 选项 1 避免了全局状态,但它弄乱了我模型中几乎每个类的接口(interface)。另一方面,选项 2 的表现力较差,因为如果不查看全局设置,您将无法判断您将获得哪种语言。此外,它在全局设置的每个类中引入了依赖关系。

    请注意,我对数据库或 ORM 实现不感兴趣;我只在域模型级别工作。

    那么我有两个具体问题:
  • 哪个是实现多语言域模型目标的最佳选择(1 或 2)?
  • 还有其他我没有考虑过的选项,它们是哪些?

  • 谢谢你。

    编辑 .有人认为这是与用户界面相关的问题,因此可以通过 .NET 中的全局化/本地化支持来解决。我不同意。仅当您知道必须在编译时向用户显示的本地化文字时,UI 本地化才有效,但这不是我们的情况。我的问题涉及编译时未知的多语言数据,因为它将在运行时作为用户数据提供。这不是与 UI 相关的问题。

    编辑 2 .请记住,Person.Position 只是用来说明问题的玩具示例。它不是真实模型的一部分。不要试图批评或改进它;这样做是没有意义的。我们的业务需求涉及很多不能编码为枚举类型或类似的属性,并且必须保持为自由文本。因此困难重重。

    最佳答案

    鉴于以下情况:

    Some use case involve setting the values for an object in all the supported languages; others involve looking at the values in one given language.



    我建议两种选择都去。这意味着持有多语言内容的 Person 和所有类都应保持该内容处于其状态,并且:
  • Position 属性应该设置/获取人在
    当前用户的语言。
  • 应该有对应的属性或方法全部
    语言设置/获取。
  • 应该有一种设置方法(如果需要,甚至可以切换)
    用户语言。我会创建一个抽象类(例如
    BaseMultilingualEntity) 与抽象 SetLanguage(Language
    lang) 方法和 CurrentLanguage getter。你需要保持
    跟踪从 BaseMultilingualEntity 派生的所有对象
    在某种会暴露语言设置的注册表中。

  • 用一些代码编辑


    public enum Language {
    English,
    German
    }

    // all multilingual entity classes should derive from this one; this is practically a partly implemented observer
    public abstract class BaseMultilingualEntity
    {
    public Language CurrentLanguage { get; private set; }

    public void SetCurrentLanguage(Language lang)
    {
    this.CurrentLanguage = lang;
    }
    }

    // this is practically an observable and perhaps SRP is not fully respected here but you got the point i think
    public class UserSettings
    {
    private List<BaseMultilingualEntity> _multilingualEntities;

    public void SetCurrentLanguage(Language lang)
    {
    if (_multilingualEntities == null)
    return;

    foreach (BaseMultilingualEntity multiLingualEntity in _multilingualEntities)
    multiLingualEntity.SetCurrentLanguage(lang);
    }

    public void TrackMultilingualEntity(BaseMultilingualEntity multiLingualEntity)
    {
    if (_multilingualEntities == null)
    _multilingualEntities = new List<BaseMultilingualEntity>();

    _multilingualEntities.Add(multiLingualEntity);
    }
    }

    // the Person entity class is a multilingual entity; the intention is to keep the XXXX with the XXXXInAllLanguages property in sync
    public class Person : BaseMultilingualEntity
    {
    public string Position
    {
    set
    {
    _PositionInAllLanguages[this.CurrentLanguage] = value;
    }
    get
    {
    return _PositionInAllLanguages[this.CurrentLanguage];
    }
    }

    private Dictionary<Language, string> _PositionInAllLanguages;

    public Dictionary<Language, string> PositionInAllLanguages {
    get
    {
    return _PositionInAllLanguages;
    }
    set
    {
    _PositionInAllLanguages = value;
    }
    }
    }

    public class Program
    {
    public static void Main()
    {

    UserSettings us = new UserSettings();
    us.SetCurrentLanguage(Language.English);

    Person person1 = new Person();
    us.TrackMultilingualEntity(person1);

    // use case: set position in all languages
    person1.PositionInAllLanguages = new Dictionary<Language, string> {
    { Language.English, "Software Developer" },
    { Language.German, "Software Entwikcler" }
    };

    // use case: display a person's position in the user language
    Console.WriteLine(person1.Position);

    // use case: switch language
    us.SetCurrentLanguage(Language.German);
    Console.WriteLine(person1.Position);

    // use case: set position in the current user's language
    person1.Position = "Software Entwickler";

    // use case: display a person's position in all languages
    foreach (Language lang in person1.PositionInAllLanguages.Keys)
    Console.WriteLine(person1.PositionInAllLanguages[lang]);


    Console.ReadKey();

    }
    }

    关于domain-driven-design - 如何创建多语言领域模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15116593/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com