Size: a a a

2021 May 02

DH

Dark Hole in dlang.ru
Я не понимаю твою логику
источник

DH

Dark Hole in dlang.ru
Вот у нас есть структура (или класс) Config
источник

DH

Dark Hole in dlang.ru
В ней нужные значения лежат как поля
источник

DH

Dark Hole in dlang.ru
Условно:
class Config {
 bool color;
 int foo;
 float bar;
}
источник

DH

Dark Hole in dlang.ru
Где-то его инициализируешь и передаёшь по всей программе
источник

DH

Dark Hole in dlang.ru
Если хочешь ленивое извлечение данных или установку — @property спешит на помощь
источник

DH

Dark Hole in dlang.ru
Опциональные данные? nullable
источник

DH

Dark Hole in dlang.ru
В чём проблема так делать?
источник

DH

Dark Hole in dlang.ru
О, ещё вариант если ты прям хочешь идти по пути наследования.
class Config {
 Value get(string name) { ... }
}

class Value {
 T as(T)() { ... }
}

(new Config()).get("hello").as!string;
источник

DH

Dark Hole in dlang.ru
(правда не получится set таким же принципом сделать)
источник

OB

Oleg B in dlang.ru
с конфигами я принял такую модель для себя: описываю для конкретного приложения структуру, содержащую весь конфиг, на основе этой структуры магией метапрограммирования делаю класс доступа к её полям (обычно это структуры по аспектам, типа настройки соединения, настройки логирования), дальше с этим классом уже работаю, переопределяю что надо, добавляю проверки и тд
источник

OB

Oleg B in dlang.ru
плюсы: есть простое описание конфига структурой (её уже можно заполнять как удобно, из json, yaml и тд), есть возможно определять поведение при выставлении новых значений, можно делать прокси-классы, которые обращаются за исходным конфигом например по сети и тд

минусы: каждая подструктура для удобства использования должна копироваться при получении из класса-обёртки
источник

EP

Egor Pugin in dlang.ru
можно сделать типизированные настройки, а в базе оно конвертится из/в строки

https://github.com/egorpugin/primitives/blob/master/src/settings/include/primitives/settings.h#L459
(плюсовый пример)
источник

KF

Konstantin Firsov in dlang.ru
А как в случае нескольких конфигов с разными ключами? Тогда на поле массив с объектами\структурами этих конфигов, в которых как-то ищется значение... или же изменяется сам процесс заполнения такого мультиконфига из нескольких источников, как оно работает?
источник

KF

Konstantin Firsov in dlang.ru
спасибо, посмотрю
источник

KF

Konstantin Firsov in dlang.ru
Ну вот как у меня сейчас сделано. Ключи находятся на статическом поле двух классов с ключами конфигов. Один - общая логика и ядро программы, второй - предметная т.е. rss и т.п., для приложения существует один конфиг и везде инжектится через сеттер базовый конфиг, а классы с ключами разные. Т.е. если контроллер дерева rss-лент наследуется от компонента ядра, который уже содержит конфиг, то без параметризации в него попадает тот конфиг, на который завязано ядро программы - т.е. базовый класс конфига.

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

ОДнако простой конфиг в общем случае - это структура данных ключ-значение по цепи файл -> ключ-значение -> объект, поэтому такой объект-конфиг с типами полей это следующий уровень апи, более высокий, а значит можно сделать шаг назад на более низкий - прямой работой с ключ-значение. Т.к. это более низкий уровень, он менее безопасен + вероятность рантаймовых ошибок, отсутствующий ключ, усложняет количество поддерживаемых типов значений и т.п, это минус.

Но для мапинга появляется синхронизация уже между двумя структурами ключ-значение, где вторая набор полей объекта, по аналогии с бд мапингом рождаются частные случаи: кол-во полей != кол-во ключей в файле, если в поле null или какая-то ерунда, то это из-за того что в файле конфига null или из-за того, что маппер косячит, файл конфига содержит ключ ключевое слово, например, "class" и имя поля не может быть именем ключа, имя ключа в файле конфига резко поменялось и т.п., грабли добавляются уже со стороны маппера, что для меня в принципе уравновешивает ошибки с работой напрямую. Ну а если dyaml выдает мне ключ-значение, то зачем мне морочиться с мапингом и делать дополнительную работу? Ну и та же классика, точка в ключе конфига "app.title", верхний и нижний регистр и т.п, к полю выдвигаются более строгие требования по именованию + соглашение о наименовании в языке, поэтому прямое отображение подходит лишь для очень простых случаев, а сложное начинает вставлять палки в колеса, особенно если есть, например, два разных типов - нужно два маппера.

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

Прошу прощения за длинный текст)
источник

EP

Egor Pugin in dlang.ru
очень всё трудно понять
источник

МВ

Макс Воробьев... in dlang.ru
а вариант сделать базовый интерфейс Value с методами get/setValue(string, string), и с реализацией такого Value  для каждого типа?
источник

g

gavr in dlang.ru
в GValue уже сделано
источник

МВ

Макс Воробьев... in dlang.ru
и Config пусть возвращает такие Value
источник