Что такое хорошая структура данных для каскадных объектов? - PullRequest
3 голосов
/ 29 декабря 2008

Мне было интересно, какой тип структур данных и шаблонов проектирования используется при реализации чего-то вроде CSS, где вы можете указать форматирование или какое-либо другое свойство на разных уровнях детализации.

Один конкретный пример, над которым я сейчас работаю, связан с интернационализацией приложения.

Прежде всего, английский является языком по умолчанию, но приложение будет использоваться в двух разных регионах: в Северной и Южной Америке и Европе. В большинстве случаев различные фрагменты текста и надписи будут одинаковыми между двумя регионами, но в некоторых случаях технические термины будут различаться в зависимости от региона. При переводе текста на другой язык некоторые из них сохраняют оригинальный английский текст для региона.

Таким образом, поиск текста для ярлыка будет работать следующим образом. Посмотрите на конкретную комбинацию региона и языка. Если ничего нет, посмотрите только на язык. Если ничего, посмотрите на сочетание английского и региона. Если ничего, посмотрите только на английский.

Я ищу наилучшие способы хранения данных этого типа в базе данных, а также в структуре данных в коде. Либо в этом конкретном случае, либо в целом для подобных ситуаций.

Ответы [ 5 ]

1 голос
/ 30 декабря 2008

Вместо того, чтобы жестко кодировать вашу последовательность в хранилище данных, вы можете использовать ее на уровне доступа в соответствии с этим псевдокодом:

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. Это означает, что у вас есть одна точка, если вам нужно посмотреть «правила», и одна точка обслуживания (включая отсутствие обслуживания хранилища данных), если вам нужно их изменить.

1 голос
/ 29 декабря 2008

Если вы используете языковые теги RFC 4646 в качестве идентификатора языка (как это делают браузеры; например, «DE-AT»), они имеют встроенную иерархическую структуру.

Для обработки поиска разбейте идентификатор по тире на список, отсортированный по убыванию длины, с нейтральным языком / языком по умолчанию (например, английским) в качестве пустой строки; в этом случае это будет "DE-AT", "DE", "" (=> "EN"). Затем найдите первое совпадение.

Я успешно использовал этот дизайн как в поиске SQL, так и в файлах.

Если у вас большое количество строк и / или локализаций, рекомендуется кэшировать ключи. Хорошо работает хеш-таблица хеш-таблиц.

1 голос
/ 29 декабря 2008

Каскадные хеш-таблицы работают хорошо. Каждая хеш-таблица имеет ссылку на другую хеш-таблицу, которую можно использовать, если ключ не найден локально. Будет хэш-таблица для каждой пары местного языка и региона, она ссылается на хеш-таблицу для своего локального языка, которая ссылается на хеш-таблицу для региона и английского языка, которая в конце концов ссылается на хеш-таблицу английского языка.

Lua имеет эту встроенную структуру в качестве фундаментальной структуры данных table . Метатабельность таблицы может использоваться для поиска пропущенных ключей. Это также может быть использовано для динамического построения иерархий классов / объектов.

1 голос
/ 29 декабря 2008

Как говорит Дуг Керри, каскадные таблицы - это путь, поэтому у вас будут ресурсы en для родового английского языка и en_US или en_UK для локалей в США и Великобритании соответственно.

Вам следует проверить свои языковые библиотеки, чтобы узнать, предоставляют ли они абстракции для этого. Например, Java предоставляет ResourceBundle, который обеспечивает иерархический запас для локалей следующим образом: javadoc для java.util.ResourceBundle

Аналогично, в GNU есть gettext, который используется во всем мире свободного программного обеспечения: домашняя страница для GNU gettext .

Вероятно, в вашей среде будет аналогичный API для обработки i18n / l10n.

1 голос
/ 29 декабря 2008

иерархически, конечно!

База данных:

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...