Обновить
0
0.5

Пользователь

Отправить сообщение

Ну ливнул, классика, мне достаточно код увидеть было по нему мне более чем понятно куда дует ветер. Смысл читать статью, там вы натягиваете сову на глобус, подбивая фактуру под то, почему сервис локатор это круто и молодежно?

Что за бред. Это сервис локатор, там в принципе без контекста протестить ничего нельзя.

Что такое namespace? Это объект, который инициализируется через IIFE. Вот в нем у нас есть поле test с нашими тестами. Чтобы его запустить, наше тест, нам нужно взять и вызвать

$.$test_run()


Под копотом там произойдет следующее. Возьмем текущий this, который $, скопируем его с перезаписью полей переданными сервисами и вызовем каждый из наших тестов с этим контекстом. А в тесте мы прокинем этот контекст в наше $app, которое потянет хрен знает что из него.

Поздравляю, чтобы протестировать $app тебе нужно поднять инфраструктуру. То есть твое app$ в принципе без инфраструктуры не существует.

Если это не сервис локатор, тогда почему, чтобы протестировать $app я должен поднять его в контексте всего приложения.

Я не могу сделать так

test('app', () => {  
    const app = new $.$app(<здесь мне нужен контекст>);
    expect(app.sayYourName()).toBe('$app');
})


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

Можно сделать так по идее

test('app', () => {  
    const app = new $.$app($)
    expect(app.sayYourName()).toBe('$app');
})


но это не точно, а проверять это мне не кайф, так как от этого кода уже кровь из глаз течет, а сути дела это не меняет.

Без передачи контекста всего окружения, которое было объявлено экспортируемым (читай как "записанным" в поля объекта, которым является namespace), начиная с корня (в нашем случае $ и далее до уровня $test) ты $app не протестируешь.

Конечно, можно возразить, мне не обязательно поднимать весь контекст, достаточно только то, от чего зависит $app. А от чего он зависит? И тут начинается анализ кода $app, потому что мы не можем определить зависимости, они не инъектируются в конструктор, они тащятся из контекста.

Подводя итоги, ты изобрел сервис локатор.

Кстати, дополню себя. В реализации с сервис локатором nin-jin-а тебе нужно поднимать в принципе инфраструктуру, так как тебе нужен контекст. В нормальном мире, ты можешь тестировать класс без поднятия какого-либо окружения, он самодостаточен, нужно лишь предоставить ожидаемые классом зависимости

nin-jin каждый раз когда не вывез
nin-jin каждый раз когда не вывез

Раз перешли на картинки

Правильное тестирование,

Это у вас верное тестирование? Человек, который лет 10 или сколько к продуктовой разработке отношения не имеет и сделал за все время реактивную либу и зверинец маргинальных технологий, а теперь предлагает всем его переизобретенный сервис локатор.

Повторюсь, это тоже самое.

new MyClass(diContainer)

Захотел я одной строчкой запустить все тесты с изоляцией.

Полез в MyClass, посмотрел что он дергает.

Ага 100500 классов, ну подменим их на то что нужно

diContainer.register(TokenA, Implementation)

и т.д.

А, так всё же вам нравится, когда вас унижают. Ну ок... Если бы вы вытащили голову из того места, которым думаете, то вместо того, чтобы повторять ту же самую глупость второй раз, надеясь на новый результат, ознакомились бы со статьёй, ссылкой на которую я с вами любезно поделился.

О началась, рефлексия, признаться честно, это оказалось легче чем я думал, вроде колос, а ножки то глиняные

Как ты его увидишь не проанализировав его?) Типа Васян написал класс SuperDruperClass$$$$$mol$$$$$$

Где то в коде такая штука

const theBestInstance = new SuperDruperClass$$$$$mol$$$$$$(this)

Я как пойму что это за коробка. Я даже не знаю от чего он зависит. Мне надо залезть в него, а там портянка на 1000 строк кода с дерганьем контекста this.$.<Имя>. Я должен видеть от чего зависит модуль, чтобы иметь представление что это за зверь такой. Это не значит что все проблемы решены, но я как минимум не стрельну себе в ногу здесь

Посмотрев на MyClass(Service1, Service2) я хотя бы могу предположить что-то. Но опять таки, мой тейк был в том, что инъекция через конструктор покажет что что-то не так, когда ты увидишь ну например такое

new MyClass(Service1, Service2, Service3, Service4, Service5, Service6, Service7, Service8, Service9)

new MyClass(context) не покажет. Это вообще сервис локатор по сути в какой-то из его форм. Я могу сделать тоже самое, только через тот же di.

new MyClass(diContainer)

Все. Это ровно ваш код, просто зависимости берутся из контейнера, а не из контекста. Для меня это черный ящик. Захочешь ты его протестировать, тебе придется полезть внутрь, понять на что нужны заглушки, чтобы инфру всю не поднимать

подразумевает что все сторы асинхронные, что может быть не так.

В примере изначальном не смотря на то, что хранилища не асинхронные, они уже в async функции, а занчит асинхронные. Так что мой await все правильно подразумевает с точки зрения исходного примера. Вы исходный пример не асинхронным тоже не сделаете. Вам придется разбить сторы на синхроныне и асинхронные. Точно также и тут.

Про поломку не понял ничего. Какой метод getDataMethod у вас общий интерфейс, адаптер для такой штуки придуман, под него и замаскирует что хотите. Ведь все эти функции это и есть те самые адаптеры, просто написанные как функции. Ведь предполагается что под капотом вы лезете в апи этих сторов, которое разное. Поздравляю, у вас адаптер

 getDataFromReduxStore()  getDataFromLocalStorage()  (await fetchDataFromBackend()

Просто здесь адаптер только под метод получения данных.

но только у вас ещё + 6 строчек никому не нужной и ничего не добавляющей обвязки. Кроме того

Очень голословно, очень. Моя "обвязка" (что блин!?, это же просто интерфейс) декларирует то, что есть какой-то стор, у которого есть методы. А что под капотом этого стора не важно.

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

 writeDataIntoReduxStore(data)  writeDataIntoLocalStorage(data)  (await writeDataIntoBackend(data)


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

Где здесь абстракция? Как-то в послденее время часто к месту и не к месту используют это слово на довольно примитивных вещах. У вас есть сторы откуда вы тащите инфу, раз вы лезете во все три стора наверное это все же какая-то связанная бизнес логика, не вижу ничего плохого объединить ее общим интерфейсом. Нет, конечно вы вольны не делать этого, если бизнес логика никогда не изменится и вам сторы больше не понадобятся и вы в этом уверен на 146%. Возможно я бы на раннем этапе не объединял, но критичного не вижу ничего тут, как-то хуже программу это не делает, а какое-то закладывание на возможное расширение уже есть. Я показал, как вижу код, который считаю в данном случае хорошим. Вы назвали это оверхедом, я назвал ваш подход write-only. Думаю каждый останется при своем.

А вы попробуйте :)

Вы не представляете сколько проблем могут породить решения, основанные на фразе «не думаю, что в будущем».

Какие хранилища, какие циклы? Это open close обыкновенный. Завтра у вас еще 10 сторов появится, ваш код будет выглядеть так?

function getData ()
   return getFromA() || getFromB() || getFromC() || getFromD() || getFromE() || <Еще десяток сторов>

Где жалобу увидели? Обычный вопрос вроде был. Назвать что-то говном, что им является, просто констатировать факт. При чем здесь конструктивность. 100500 статей написано почему редакс говно.

Это реакция после прочтения
Это реакция после прочтения

Мне получается чтобы протестировать какой-то класс, ну тот же самый $app нужно будет пойти в класс, посмотреть что он дергает через контекст, чтобы знать его зависимости и соответсвенно подменить их. То есть я не вижу от чего зависит класс, для меня это черная коробка. Придется его проанализировать, чтобы понять что подменять. Но это пол беды, основное, что тревожит, это скрытие "запаха" кода. Явная инъекция в конструктор класса позволяет обнаружить перегрузку класса ответсвенностью. Зависимости из контекста скрывают этот факт. Мы не можем понять, а не дохрена ли наш класс делает. Это то, на что наводят мысли, когда ты в классе видишь миллион зависимостей. Соответсвенно мы можем отлавливать такие проблемы на этапе проектирования, а не обнаружить спустя время, что наш $app это божественный класс

Да там не сложно, дешевые набросы и сведение все к тому, что гения никто не понял, вон он 10 лет говно пилит)

Он сейчас в другом треде со мной воюет, дима не придет

А за что минус, за резкость? Ну так мы тут все взрослые мужи, нечего сопли жевать. Если мне покажут пример кода на реакт + редакс, боевого, желательно с оркестрацией взаимодействия пары сервисов и моделей, который не выглядит вырвиглазно, то буду признателен и с удовольсвием признаю, что мое мнение ошибочно.

Но в том же редаксе, вроде как есть санки как место для такого рода оркестрации, но при этом заинжектить туда зависимость в виде сервисов ты не можешь. Есть костыль для санков extraArgument, в теории туда можно прокинуть контейнер с зависимостями, но если тебе потребуется другой контейнер или очистить этот ничего не выйдет. Поэтому единственный путь, это все провернуть, передать зависимости как аргументы при вызове санка, а передать мы можем только из места вызова, а это реакт. Вот и получается, что часть логики лежит в ui слое, часть в санке и т.д. Думаю это самый чистый способ в принципе инкапсуляции бизнес логики в рамках редакса

Унижают? Вы если и связаны как-то с унижением, то как объект на который направлено действие. Но фиксация странная. Тут нужно к специалисту, к какому зависит от того получаете ли вы удовольствие или нет, или это была попытка пригласить в мол сообщество?😁

Хз какую задачу вы там придумали и решили в моем примере. Это просто пример класса и инъекции его в какой-то компонент с целью вызова какого-то метода. А в вашем зверинце это как решается?

А к чему этот мув и при чем здесь кнопка? Я пример кода скинул, чтобы продемоснтрировать, что эти фразы про «все пишут плохо на реакте» - это бредятина.

Ну если чтение ифов это ментальная нагрузка, тогда сомневаюсь, что человеку стоит разрабатывать, не дай бог еще с замыканием столкнется или с рекурсией.

Информация

В рейтинге
2 210-й
Зарегистрирован
Активность