用存储库模式隐藏国际化

时间:2014-01-13 16:13:29

标签: c# design-patterns internationalization repository-pattern

我试图创建一个国际化的商店作为一个例子。为了公开每个属性具有不同翻译的Product

这是我的尝试,在此阶段仅实施CR的R。 (代码数量道歉)

void Main()
{
    var repo = new ProductRepository();

    var enGb = repo.GetProduct(1, "en-GB");

    Console.WriteLine("en-GB: {0} {1}", enGb.Name, enGb.Description);

    var enUS = repo.GetProduct(1, "en-US");

    Console.WriteLine("en-US: {0} {1}", enUS.Name, enUS.Description);
}

private static IEnumerable<HiddenProduct> hiddenProducts = new List<HiddenProduct> { new HiddenProduct { Id = 1, NameId = 1, DescriptionId = 2 } };
private static IEnumerable<Translation> translations = new List<Translation>
{
    new Translation { Id = 1, Locale = "en-GB", Text = "Hello" },
    new Translation { Id = 1, Locale = "en-US", Text = "Howdy" },
    new Translation { Id = 2, Locale = "en-GB", Text = "World" },
    new Translation { Id = 2, Locale = "en-US", Text = "America" }
};

public class Product
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }
}

public class HiddenProduct
{
    public int Id { get; set; }

    public int NameId { get; set; }

    public int DescriptionId { get; set; }
}

public class ProductRepository
{
    public Product GetProduct(int id, string locale)
    {
        var hidden = hiddenProducts.SingleOrDefault(p => p.Id == id);

        if (hidden == null)
            return null;

        var name = translations.FirstOrDefault(a => a.Id == hidden.NameId && a.Locale == locale);

        var description = translations.FirstOrDefault(a => a.Id == hidden.DescriptionId && a.Locale == locale);

        if (name == null || description == null)
            return null;

        return new Product { Id = id, Name = name.Text, Description = description.Text };
    }
}

public class Translation
{
    public int Id { get; set; }

    public string Locale { get; set; }

    public string Text { get; set; }
}

我的问题是:

  • 这是否在存储库模式中有意义?

  • 我是否走在正确的轨道上?

  • 有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

我无法告诉您有关存储库模式的更多信息,但我可以告诉您有关此代码的信息。

你正在使用LINQ。这可能是一件好事,但我不太确定这种特殊情况下的表现。当你使用可枚举时,在最坏的情况下,你需要在平均情况下O(n)进行O(n / 2)次比较。我认为这没有道理。通常,对于多个属性的翻译,您要做的事情(特别是涉及某种关系数据库时......)将是:

  1. 为每个产品创建唯一ID(可以是GUID或其他内容)
  2. 一次阅读给定语言(仅限此语言)的翻译。在一个用户的环境中,您通常希望以他/她的语言显示多个产品,当然您不想混合语言。
  3. Dictionary<GUID, string>可能更适合(缩短查找时间,即资源消耗)。但无论如何,您可能直接从记录集创建已翻译的产品列表,其中您具有唯一的ID以及名称和描述 - 它可以“即时”完成。
  4. 好的,我相信这只是一个例子,不是吗?通常, 更好 使用常见的本地化技术(在.Net的情况下,这意味着.resx文件和内容)而不是重新发明轮子。除非你真的知道自己在做什么,否则你很可能会创建一个I18n问题。我只能向你保证,翻译资源设计背后有原因...... 所以你真的不应该为设计自己而烦恼。 也就是说,除非你真的需要提出自己的解决方案,例如你正在展示的动态翻译问题(在这个例子中,翻译会经常更改,你需要一个简单的机制来更新它们并根据它们进行调整客户的需求)。

答案 1 :(得分:0)

想想这个

User: LanguageId

Content: ContentId

Phrase: PhraseId, ContentId

说明:

用户提供语言。内容请求提供ContentId。在每种语言中,您都应该有一个描述内容的短语。

我想,你在某处。