Выбор правильной структуры для хранения многих значений аналогичного типа с различными параметрами / свойствами - PullRequest
0 голосов
/ 23 мая 2019

Я делаю экран настроек видео для приложения, и мне нужен способ сохранить каждый параметр перед отправкой его менеджеру UI, который будет создавать элементы HTML. Ранее я хранил их в виде массива примерно так:

let options = [
            new BoolOption("Ragdolls", 1, "description here"),
            new QualityOption("SkeletalMeshLODBias", 0, "description here"),
            new ResolutionOption("Character Texture Resolution", 4, "description here"),
            new Option("Video Memory Texture Pool", [150, 300, 600], 0, "description here")
        ]

Недостатком этого подхода является то, что, поскольку хранится много типов, а их параметры не совпадают, читаемость ухудшается, особенно при работе с большим количеством значений. Имея это в виду, я сделал это объектом / словарем и написал функцию для преобразования его обратно в массив:

let optionsDictionary = {
    ragdolls: {
        name: "Ragdolls",
        type: BoolOption,
        defaultIndex: 1,
        description: "description here"
    },
    skeletalMeshLODBias: {
        name: "SkeletalMeshLODBias",
        type: QualityOption,
        defaultIndex: 0,
        description: "description here"
    },
    characterTextureRes: {
        name: "Character Texture Resolution",
        type: ResolutionOption,
        defaultIndex: 4
    },
    texturePool: {
        name: "Video Memory Texture Pool",
        type: Option,
        states: [150, 300, 600],
        defaultIndex: 0,
        description: "description here"
    },
}



let optionsDictionaryToOptionsArray = (optionsDictionary) => {
    let options = []
    for (let key in optionsDictionary) {
        let option
        if (optionsDictionary.hasOwnProperty(key)) {
            let setting = optionsDictionary[key],
                name = setting.name,
                type = setting.type,
                defaultIndex = setting.defaultIndex,
                description = setting.description || ""

            switch (type) {
                case Option:
                    let states = setting.states
                    option = new Option(name, states, defaultIndex, description)
                    break
                case BoolOption:
                    option = new BoolOption(name, defaultIndex, description)
                    break
                case RangeOption:
                    let min = setting.min, 
                        max = setting.max
                    option = new RangeOption(name, min, max, defaultIndex, description)
                    break
                case QualityOption:
                    option = new QualityOption(name, defaultIndex, description)
                    break
                case ResolutionOption:
                    option = new ResolutionOption(name, defaultIndex, description)
                    break
                default:
                    throw new Error()
            }
        }
        options.push(option)
    }
    return options
}

Но я все еще чувствую, что его можно улучшить или сделать с помощью более элегантного решения, поскольку ключи в каждом из свойств объекта словаря зависят от его .type. Может быть, я даже усугубил второй подход. Есть предложения?

1 Ответ

0 голосов
/ 23 мая 2019

Я полагаю, что ваш вопрос может быть предвзятым, так как люди могут не согласиться с тем, что выглядит "лучше". Поэтому я просто упомяну другую опцию форматирования, доступную здесь: Конструкторы, принимающие параметры через один объект :

let options = [
  new BoolOption({
    name: 'Ragdolls',
    defaultIndex: 1,
    description: 'description here'
  }),
  new QualityOption({
    name: 'SkeletalMeshLODBias',
    defaultIndex: 0,
    description: 'description here'
  }),
  // ...
  // ...
  // ...
];

Переключение на этот формат практически не требует рефакторинга - для конструктора, подобного:

let BoolOption = function(name, defaultIndex, description) {
  // ...
};

Просто добавьте { и }, окружающие параметры, и все должно работать одинаково:

let BoolOption = function({ name, defaultIndex, description }) {
  // ...
};
...