@kotlin_lang

Страница 877 из 982
Руслан
18.09.2018
14:43:39
ServiceLoader
Service Locator т.е.)

Что в общем-то не DI

Google
Mikhail
18.09.2018
14:44:04
Service Locator т.е.)
и чем плох ServiceLocator в данном случае?

Руслан
18.09.2018
14:44:19
и чем плох ServiceLocator в данном случае?
Все тем же - ошибки на рантайме

Mikhail
18.09.2018
14:44:31
Руслан
18.09.2018
14:44:32
А у нас же тръ фп, компайл там.

Mikhail
18.09.2018
14:44:52
у тебя есть context и в нем есть все что может понадобится любому плагину, нет?

Quantum Harmonizer
18.09.2018
14:45:01
Все тем же - ошибки на рантайме
нет, если заранее договориться о том, какие объекты кор предоставляет

Руслан
18.09.2018
14:45:02
какие еще ошибки?
ну выше вы с Andrey объясняли самый широкий спектр ошибок к оторым приводит container di

Mikhail
18.09.2018
14:45:59
Окей, а каков твой подход? Ведь ты же тоже предлагаешь ServiceLocator

просто формат немного другой, разве нет?

Руслан
18.09.2018
14:47:31
Я говорю что есть куча задач где не будет в вашем DI никакой compile-time safety. И как пример привожу вот эту задачу.

И вот тут spring намного лучше бы отработал

т.к. он проинициализировал зависимости не только у Plugin, но и у всех зависимостей Plugin внутренних.

Quantum Harmonizer
18.09.2018
14:48:48
Google
Руслан
18.09.2018
14:49:40
«Если хоть где-то нет compile-time safety, давайте вообще выбросим его.»
У меня почти в кажом проекте рабочем есть такого рода задачи. Да весь bootique на этом построен)

Andrey
18.09.2018
14:49:56
Да, такой вот не очень хороший подход, но plugin может хотеть любую часть core
Мягко говоря, не очень. Это нарушение изоляции core в чистом виде. То есть, на этом моменте вы говорите, что интерфейс, предоставляемый плагинам будет динамически расширяться и изменяться при изменениях в core. Это какбе нарушение DIP, где каждый компонент декларирует интерфейс, как с ним работать. А у вас core такого интерфейса не декларирует.

Andrey
18.09.2018
14:51:00
Конечно, можно сказать что плагину лезть в кор не нужно, и это идеальное решение проблемы)
Ну так и надо сказать. Иначе у вас связность по коду появится.

Quantum Harmonizer
18.09.2018
14:51:50
Конечно, можно сказать что плагину лезть в кор не нужно, и это идеальное решение проблемы)
А можно сделать сервисЛокатор явным и не закладываться на особенности реализации и не ломать совместимость.

Руслан
18.09.2018
14:51:52
Ну так и надо сказать. Иначе у вас связность по коду появится.
Только проблема в том что плагин может и в базу захотеть сходить, и черти что.

Mikhail
18.09.2018
14:52:13
Я говорю что есть куча задач где не будет в вашем DI никакой compile-time safety. И как пример привожу вот эту задачу.
как раз таки в том чтобы передать Context, в котором уже содержатся все нужные зависимости - есть

Andrey
18.09.2018
14:52:19
То есть разделение на core и plugin у вас не работает де факто. Фактически, у вас монолит.

Mikhail
18.09.2018
14:52:38
передавать локатор и передавать граф - разные вещи

Andrey
18.09.2018
14:53:23
Только проблема в том что плагин может и в базу захотеть сходить, и черти что.
Зачем плагину самому ходить в базу? Он должен поход в базу делегировать core через предоставленное интерфейсом API

Mikhail
18.09.2018
14:53:28
Andrey
18.09.2018
14:54:19
а смысл тогда иметь отдельный плагин?
Вот и я не пойму, зачем в связанном по коду монолите что-то называть плагином. Оно от этого плагином не станет.

Руслан
18.09.2018
14:54:35
Зачем плагину самому ходить в базу? Он должен поход в базу делегировать core через предоставленное интерфейсом API
Вы пытаетесь уменьшить скоуп того что плагину нужно, а задача в корне остается той же.

а смысл тогда иметь отдельный плагин?
В том что есть core, и каждый клиент может этот core расширять как ему хочется. Без перекомпиляции

Quantum Harmonizer
18.09.2018
14:55:24
что отвалится в следующей версии — никто не знает

Руслан
18.09.2018
14:56:14
...и без совместимости
Core очень стабилен просто, старое не выкидывается, а надолго деприкейтится. Опять же это аут оф скоуп

Andrey
18.09.2018
14:56:33
В том что есть core, и каждый клиент может этот core расширять как ему хочется. Без перекомпиляции
И без безопасности. Любой клиентский плагин может с чем угодно творить что угодно. Беспредел прям и анархия.

Quantum Harmonizer
18.09.2018
14:56:46
Google
Mikhail
18.09.2018
14:57:45
Core очень стабилен просто, старое не выкидывается, а надолго деприкейтится. Опять же это аут оф скоуп
ну значит у него есть какое-то стабильное апи для получения зависимостей

Andrey
18.09.2018
14:58:06
Вы пытаетесь уменьшить скоуп того что плагину нужно, а задача в корне остается той же.
Я не пытаюсь уменьшить скоуп. Смысл в том, чтобы явно декларировать, на что плагин может рассчитывать. Это и есть интерфейс core

Руслан
18.09.2018
15:00:14
В общем резюмируя, вы предлагаете все что я нежно ручками в core main насоздавал, запихнуть в мапу, или в мапу обернутую в интерфейс и передать в метод Plugin.setContext(deps)?

Andrey
18.09.2018
15:01:37
В общем резюмируя, вы предлагаете все что я нежно ручками в core main насоздавал, запихнуть в мапу, или в мапу обернутую в интерфейс и передать в метод Plugin.setContext(deps)?
Ни в коем случае. В интерфейс или несколько, представители которых и будут переданы плагину. Инкаких мапов.

Mikhail
18.09.2018
15:01:39
почему контекст ассоциируется с мапой?

Quantum Harmonizer
18.09.2018
15:02:06
Quantum Harmonizer
18.09.2018
15:02:22
почему контекст ассоциируется с мапой?
Потому что не все работали с андроидом ?

Andrey
18.09.2018
15:02:38
> или в мапу обернутую в интерфейс
Нет, не в мапу. Мапа сотрёт типизацию.

Руслан
18.09.2018
15:03:22
Ну условно. В такой жирный класс, в которым X полей просто для того чтобы использовать его дальше как service locator

Mikhail
18.09.2018
15:03:38
> или в мапу обернутую в интерфейс
как хочешь, главное чтобы все втои зависимости лежали в ней еще в compile-time

Quantum Harmonizer
18.09.2018
15:05:26
Map из Class<T> в T ?

Руслан
18.09.2018
15:05:48
Что значит условно мап?
В такой жирный класс, в которым X полей просто для того чтобы использовать его дальше как service locator

Andrey
18.09.2018
15:07:15
В такой жирный класс, в которым X полей просто для того чтобы использовать его дальше как service locator
Это уже лучше, так как у каждого поля будет различимый тип, в отличие от типов значений в мапе. Плюс это потребует все поля проинициализировать, что проверяемо компилятором.

Andrey
18.09.2018
15:09:22
Ну теоретически так конечно можно написать, только на практике получится ужасный шаблонный код
Я так пробовал. Какой-то ужасной шаблоности не заметил. Вот мапа действительно ужасна, так как для неё вообще ничего не проверяется во время компиляции.

Тимур
18.09.2018
15:13:56
вопрос допустим у меня есть иммутабельные data классы, то бишь все данные в них описаны как val я загружаю их содержимое из json и предположим некоторые их этих классов имеют ссылки друг на друга, причем циклические например, объект A имеет ссылку на B, а тот обратно и получается что чтобы создать A, его надо проинициализировать ссылкой на B, который уже создан но чтобы создать B должен быть готов A вопрос: можно ли такое как-то загрузить и создать?

Google
Andrey
18.09.2018
15:14:09
Всё это восходит к рназнице между бестиповым лямбда исчислением и типизированным. В бестиповом выражения короче, но гораздо меньше возможностей проверки их корректности. В типизированном надо, о боже, писать сигнатуры типов. Зато проверка корректности хороша. Передача мапы, как вы предлагаете, пример бестипового выражения. КМК это противоречит идеологии Kotlin, так как он позиционируется, как строго типизированный язык.

Тимур
18.09.2018
15:16:09
А как вы изначально такие объекты создавали для сериализации в JSON?
ну например, в текстовом редакторе или еще каком-то снаружи

Andrey
18.09.2018
15:17:24
ну например, в текстовом редакторе или еще каком-то снаружи
А как у вас в JSON ссылка на объект описана, так что она циклическая? Что-то не представлю. Можно пример JSON?

Тимур
18.09.2018
15:19:57
например, по имени файла файл a.json { "friend": "\b.json" } файл b.json { "friend": "\a.json" } когда десериализую, поля friend должны превратиться в прямые ссылки на соответствующие объекты

Тимур
18.09.2018
15:21:02
Mikhail
18.09.2018
15:21:39
может быть есть другой способ решить задачу? например, указывать id друга а не друга целиком

Admin
ERROR: S client not available

Тимур
18.09.2018
15:22:26
Так десериализуй friend как String
потом пользоваться неудобно, надо хранить какой-то глобальный map<String,Any>, протягивать везде на него ссылку, кастить эти Any к нужным типам

Руслан
18.09.2018
15:22:51
Так десериализуй friend как String
Ну просто потом этап резолва в удобные объекты этой вакханалии

Andrey
18.09.2018
15:23:40
например, по имени файла файл a.json { "friend": "\b.json" } файл b.json { "friend": "\a.json" } когда десериализую, поля friend должны превратиться в прямые ссылки на соответствующие объекты
С точки зрения неизменяемости, одна из ссылок на объект должна быть ленивой. С точки зрения хаков - неизменяемые поля можно менять рефлексией ??

Mikhail
18.09.2018
15:24:19
а еще можно не пытаться натянуть сову на глобус

Andrey
18.09.2018
15:24:42
а еще можно не пытаться натянуть сову на глобус
Можно, но человек не признаётся, зачем ему такое.

Тимур
18.09.2018
15:28:06
а еще можно не пытаться натянуть сову на глобус
есть данные в json они могут ссылаться друг на друга их надо загрузить в объекты они read only, то есть хотелось бы запретить их менять после загрузки почему сову?

кстати необязательно в json, просто данные которые где то лежат, грузятся и потом не меняются

но со ссылками

Mikhail
18.09.2018
15:30:14
а почему бы не заменить ссылки на id (ссылки)?

ты ведь в JSON не пытаешься данные запечь в обхекты?

Google
Руслан
18.09.2018
15:30:46
есть данные в json они могут ссылаться друг на друга их надо загрузить в объекты они read only, то есть хотелось бы запретить их менять после загрузки почему сову?
interface Friend { val friend: Friend } class ActualFriend(override var friend: Friend) : Friend Может так? Все как в жизни - говорят что навсегда, а на деле меняются)

Как заставить с этим работать ObjectMapper - для меня вопрос. Все эти ссылки врядли будут легко решаться на его уровне.

Тимур
18.09.2018
15:33:08
а почему бы не заменить ссылки на id (ссылки)?
потому что потом придется в рантайме резолвить эти id, которые после загрузки уже не нужны, нужны прямые ссылки ну то есть так сделать конечно можно, но это плохое решение, лучше даже отказаться от иммутабельности и заменить val на var

Mikhail
18.09.2018
15:36:18
как бы какая разница, сслыка у тебя на уровне байткода или кода

Тимур
18.09.2018
15:39:41
кажется, что ок решение иметь хранилище, которое может в Id -> Friend. Гораздо лучше, чем уже иметь все ссылающееся на всех
придется везде тянуть ссылку на это хранилище и еще кастить при резолве в нужный тип, потому что он не один например класс A ссылается на класс B, класс C на класс D и так далее

Тимур
18.09.2018
15:40:36
а так не надо будет кастить?
если все ссылки разрешены на этапе загрузки, то не надо

Mikhail
18.09.2018
15:41:07
если все ссылки разрешены на этапе загрузки, то не надо
а как ты сделаешь поле с динамически изменяемым типом? или А всегда ссылается на B?

если так, то передай ему функцию Id -> B

Mikhail
18.09.2018
15:43:17
ну тогда той штуке, которая работает с А не нужно ничего кастить, она всегда будет пользоваться Id -> B

Тимур
18.09.2018
15:46:04
ну тогда той штуке, которая работает с А не нужно ничего кастить, она всегда будет пользоваться Id -> B
тогда это не один глобальный map, а много придется делать этих map, по числу типов и тянуть ссылки не на один, а на несколько сразу

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

Руслан
18.09.2018
15:51:38
Ну хз, котлиновский List так по сути работает

Тимур
18.09.2018
15:52:00
ну в принципе да

Andrey
18.09.2018
15:52:44
есть данные в json они могут ссылаться друг на друга их надо загрузить в объекты они read only, то есть хотелось бы запретить их менять после загрузки почему сову?
fun main(args: Array<String>) { var b: B? = null val bRef: () -> B = { b!! } val a = A(bRef) b = B(a) println(a.b) println(b.a) } class A(bRef: () -> B) { val b: B by lazy(bRef) } class B(val a: A)

Как-то так мы сову на глобус и натянем

Тимур
18.09.2018
15:57:58
прошил ссылки, отдал интерфейс - у тебя все immutable для клиента
да, наверное надо будет подумать в этом направлении

Страница 877 из 982