什么是级联对象的良好数据结构?

时间:2008-12-29 18:39:26

标签: design-patterns data-structures internationalization

我想知道在实现像CSS这样的东西时使用了什么类型的数据结构和设计模式,你可以在不同的粒度级别指定格式或其他属性。

我目前正在研究的一个具体例子涉及应用程序的国际化。

首先,英语是默认语言,但该应用程序将在美洲和欧洲两个不同的地区使用。在大多数情况下,两个区域之间的各种文本和标签将是相同的,但在某些情况下,技术术语将根据区域而有所不同。在将文本翻译成其他语言时,有些人会保留该地区的原始英文文本。

所以查找标签的文本会像这样工作。看看区域和语言的具体组合。如果没有,请仅查看语言。如果没有,请看英语和地区的组合。如果没有,请只看英文。

我正在寻找将这种类型的数据存储在数据库中以及代码中的数据结构中的最佳方法。无论是在这种特定情况下,还是通常用于这些类型的情况。

5 个答案:

答案 0 :(得分:1)

等级,当然!

数据库:

create table Element 
(
    Id int not null,      --primary key
    ParentId int null,    --parent element foreign key
    tag varchar(64)       --etc
)
create table ElementProperty
(
    Id int not null,          --primary key
    ElementId int not null,   --owning element
    PropertyName varchar(64) not null,
    PropertyValue varchar(512) null
)

对象:

public class Element
{
    public string Tag;    //use a property instead though
    public Element ParentElement;
    public IDictionary<string,string> CssProperties;
    public string GetCssPropertyValue(string propertyName)
    {
        if (CssProperties.HasKey(propertyName))
        {
            return CssProperties[propertyName];
        }
        if (ParentElement != null)
        {
            return ParentElement.GetCssPropertyValue(propertyName);
        }
        return null;
    }
}

答案 1 :(得分:1)

级联哈希表运行良好。如果未在本地找到密钥,则每个哈希表都有一个指向另一个哈希表的链接。每个本地语言和区域对都有一个哈希表,它链接到本地​​语言的哈希表,链接到该区域的哈希表和英语,最后链接到英语哈希表。

Lua将此结构作为其基本数据结构内置。表的元表可用于满足缺失键的查找。这也可以用于动态构建类/对象层次结构。

答案 2 :(得分:1)

正如Doug Currie所说,级联表是可行的,所以你将拥有通用英语的“en”资源,以及美国和英国语言环境的“en_US”或“en_UK”。

您应该检查您的语言库,看看它们是否提供了抽象。例如,Java提供ResourceBundle,它以这种方式为语言环境提供分层回退:javadoc for java.util.ResourceBundle

类似地,GNU具有在整个自由软件世界中使用的gettext:home page for GNU gettext

您的环境可能会有类似的API来处理i18n / l10n。

答案 3 :(得分:1)

如果您使用RFC 4646语言标记作为您的语言标识符(就像浏览器一样;例如“DE-AT”),它们具有内置的层次结构。

要处理查找,请将破折号处的标识符分解为按长度减少排序的列表,并使用中性/默认语言(例如英语)作为空字符串;在这种情况下,这将是“DE-AT”,“DE”,“”(=&gt;“EN”)。然后找到第一场比赛。

我已经在SQL和基于文件的查找中成功使用了这种设计。

如果您有大量字符串和/或本地化,建议缓存密钥。哈希表的哈希表运行良好。

答案 4 :(得分:1)

不是在数据存储中对序列进行硬编码,而是根据此伪代码在接入层中驱动它:

string lookup(key, language, region) {
    string result = datasearch(key, language, region)
    if result == null {
        result = datasearch(key, language, "")
    }
    if result == null {
        result = datasearch(key, "EN", region)
    }
    if result == null {
        result = datasearch(key, "EN", "")
    }
    return result
}

优点:

  1. 代码的所有其他部分都会调用此单lookup例程,因此序列恰好位于一个位置。

  2. 序列未嵌入数据存储区。

  3. 这意味着如果您需要更改它们,如果您需要查看“规则”和一个维护点(包括没有数据存储维护),那么您有一个要点。