Тараканы в статье точно такие же как и у ECS, тут нету никакого выигрыша. Если поставить задачку реиспользовать систему ECS для разных типов данных, то получится точно так же: - Отдельно код проброса геттеров из конкретных компонентов в абстрактную общую часть логики из системы. - Отдельная абстрактная часть логики, в которой работа происходит точно так же как и через IAtomicValue, но через геттеры, чтобы не завязываться на сигнатуру конкретных компонентов. Просто в ECS всем обычно лень писать геттеры и связывание на каждый универсальный чих, и по этому в универсальную логику пихают целые компоненты, дополнительно делая сами компоненты более универсальными и атомарными. Так что аргумент, что это неECS, в конкретном частном исполнении, имхо, не засчитан.
Для целевого возраста может стоит добавить больше мелкого но приятного интерактива. Например, при описании каждого из коллайдеров в отводке написать инструкцию как закинуть его в пустую сцену и нажав Play чтобы он столкнулся с другим кинетическим коллайдером-телом. Это отвлечёт от темы, но зато приятно подкрепит любопытство, что есть ключ к успеху.
А разве не наоборот? Сначала интерфейс, затем тест использования, а только потом реализация. Получается надо и апи спрогнозировать, и варианты его использования, правильные и не правильные.
Скачав бесплатные ассеты с ассет стора, подписав приложение Android SDK сборку из движка Unity? Ох забомбит сейчас в комментах от такого лицемерия...
традиций, которые весьма отличаются от западных
Если вы про отсутствие гуманнистических принципов, перекладывание ответствености, сокрытие настоящих причинно-следственных связей и бесконечные рефлексии по СССР, то позор таким традициям. Вы пытаетесь воодушевить на изменения в рамках фреймворка который несёт вред и работает неисправно, нечего этим заниматься, нужно пересматривать фреймворк, и только это и нужно делать.
Стоит начать с того кому принадлежит RuStore, и по какой причине он вообще существует, прежде чем рассуждать о чем то духовно-полезном. И тем более делить с этой площадкой прибыль.
Мне кажется что 3 и 4 пункты как раз в Zenject есть. Это момент когда у рутового объекта будет вызван единственный Resolve. Этот объект и может иметь единственную точку входа и единственный Update() метод во всём проекте, и дальше работать уже со своим деревом просто как c C# классами.
А вот как раз 5 и 6 и не должны быть в функционале контейнера, и если в сахаре Zenject это есть, то использовать то не стоит.
Всё так, но почему в примерах статьи так много наследников от MonoBehaviour когда это обычные классы которые нуждаются в конструкторе?
Не нужно иметь под рукой сервис локатор или метод GetService, если в конструктор всё приходит, и выстроено в правильном порядке. А то что накликано в юнити мышкой, ну фиг знает, скорее всего DI нарушен многократно.
Во первых, они построены на инверсии управления и забирают у разработчика возможность управлять потоком исполнения. И если тебе нужно перестроить ход инициализации приложения, то это может очень быть проблематично.
Так как управлять потоком выполнения на самом деле мешает Юнити и неопределённость вызова методов у MonoBehaviour. Как раз это и корень проблемы. А например конструкторы - не важно кем выполненные, не являются такой проблемой. И не важно, выполняет их контейнер активатором или сам рантайм.
И действительно, в Zendject написано 90% бесполезного мусора, который только мешает понимать суть проблемы, тк этот сахар живёт по правилам убогого фреймворка. Но сама суть Di от этого хуже не становится, просто нужно использовать инъекцию только в конструктор и абстрактные фабрики. Для всех случаев в разработке игр этого будет достаточно. Единственный ООП кейс в котором будет неудобно, это параметризированный конструктор, где сигнатура зависит от типа. Такое скорее всего можно обойти абстрактным методом Init(x, y) у общего типа, и скрыть внутри своей фабрики, или наоборот, сделать пост-иньекцию в метод, а сами конструкторы сделать одинаковыми.
Когда плюсы проявляются сильнее минусов? Для относительно простых приложений.
Я бы не согласился что так проще. Это вопрос первоначального мышления и проектирования приложения. Либо мыслишь и проектируешь в древовидном графе, либо наоборот, не думая пишешь куски кода, а потом пытаешься их соеденить, и называешь это гибкость. Если всё время писать плохой код то кажется что его легче писать. И чаще всего плохой код как раз в маленьких проектах и обитает, от сюда и неправильный вывод, что сервис локаторы или синглтоны выгодны для мелких проектов.
Кажется, научное сообщество сводится к тому что это очень близко к анти-паттерну, согласно книгам Р. Мартина и М. Симана. В первую очередь из-за ошибок времени вополнения. И конечно всё дерево связей создать один раз в compositionRoot не является возможным в более менее большом проекте, или DI будет заканчиваться именно там где начнутся new() по коду. Рано или поздно в любом проекте придется пересоздавать части графа и переиспользовать код. Не говоря уже о более мелких примитивах где напрашиваются абстрактные фабрики, знающие о скрытых зависимостях. Там где можно не писать тест на резолв, а увидеть сразу ошибку компиляции это всегда выигрыш. А если речь о большой распределённой команде, то отладка багов кривого графа связей это большая боль. Соответственно - если в смежной команде кто-то заюзал сервис локатор и выдает вам инструкции как зарегать его зависимости перед использованием кода, лучше сказать "не юзай антипаттерны" и отправить переделывать.
Самый чистый код - код который можно написать используя только иньекцию в конструктор и абстрактные фабрики. А потом уже для оптимизации написания их конструкторов можно заюзать DI контейнер.
Рефлексия - это набор еще более худших антипаттернов, так как нарушить SOLID принципы можно дуновением строки кода.
Еще добавлю, что технически — сцена и есть префаб. Но исторически помимо данных о префабе в сцене еще куча всего дополнительного тянется. Еще сложность со сценами при работе с бандлами дополнительная, тк в Юнити есть разделение форматов и поведения с ними при асинхронной загрузке. + при сборке Юнити делает еще один дополнительный невидимый бандл, в который кладет сцены из списка Build Settings и принудительно поднимает в память первую сцену из списка при загрузке движка и до инициализации скриптов.
Сцены хороши и сейчас для изоляции физических миров или ресурсов, но я по возможности создаю их на лету. Еще в случае если приходится пользоваться лайтмапами или статическим батчингом то я использую сцены.
Ну примерно да. Иметь серию вложеных префабов, по мере надобности реиспользования в виде дерева. Тогда некоторые ветки и листы будут одинаковыми между сценами, и менять можно будет на уровне файла префаба. Что в этом случае стоило бы автоматизировать, так это проверку на оверрайды и циклические ссылки, собственно чтобы не иметь их.
Я бы рекомендовал сразу в сценах организовывать переиспользование через префабы и их варианты, чтобы в сценах был минимум вариаций и менять всё можно будет в одном месте. Не вижу особого смысла иметь например уникальные канвасы в каждой сцене. К тому же в примерах через скрипты выставляются одинаковые значения для всех сцен. Чем меньше оверрайдов в сценах тем легче работа обычно.
Вообще сейчас в юнити сцена это устаревший артефакт, на который лишь завязано освещение и костыль работы с бандлами сцен. Если бы не это, сцены вообще стали бы антипаттерном имхо.
Рекомендую не использовать к версиям слова «старше\младше» тк это сложнее для чтения. Если версия ядра старше 1.1.18100.6
Равно: Если версия ядра меньше 1.1.18100.6
Да, согласен. Я не правильно выразился. Я хотел сказать что универсализация апи через сигналы а затем разворачивание обратно не обязательно для ФСМ. Как альтернатива — сделать интерфейс с конкретным и типизированным апи для автомата и реализовать его и в контексте (и пробрасывать сразу в текущий стейт) и в абстрактном стейте (пустыми реализациями например). И в необходимых реализациях уже самих стейтов оверрайдить методы на которые нужно реагировать. Тогда страшный свитч исчезнет, и сигнатуры все будут строгими.
Тараканы в статье точно такие же как и у ECS, тут нету никакого выигрыша. Если поставить задачку реиспользовать систему ECS для разных типов данных, то получится точно так же:
- Отдельно код проброса геттеров из конкретных компонентов в абстрактную общую часть логики из системы.
- Отдельная абстрактная часть логики, в которой работа происходит точно так же как и через IAtomicValue, но через геттеры, чтобы не завязываться на сигнатуру конкретных компонентов.
Просто в ECS всем обычно лень писать геттеры и связывание на каждый универсальный чих, и по этому в универсальную логику пихают целые компоненты, дополнительно делая сами компоненты более универсальными и атомарными.
Так что аргумент, что это неECS, в конкретном частном исполнении, имхо, не засчитан.
Для целевого возраста может стоит добавить больше мелкого но приятного интерактива. Например, при описании каждого из коллайдеров в отводке написать инструкцию как закинуть его в пустую сцену и нажав Play чтобы он столкнулся с другим кинетическим коллайдером-телом. Это отвлечёт от темы, но зато приятно подкрепит любопытство, что есть ключ к успеху.
А разве модель есть в доступе для запуска локально? На сайтах не вижу такого, только веб интерфейс.
А разве не наоборот? Сначала интерфейс, затем тест использования, а только потом реализация. Получается надо и апи спрогнозировать, и варианты его использования, правильные и не правильные.
А между прочем, статья то хорошая. Может быть букв не густо, но я полностью согласен с изложенным и вижу ценность иатериала для коммьюнити.
Скачав бесплатные ассеты с ассет стора, подписав приложение Android SDK сборку из движка Unity? Ох забомбит сейчас в комментах от такого лицемерия...
Если вы про отсутствие гуманнистических принципов, перекладывание ответствености, сокрытие настоящих причинно-следственных связей и бесконечные рефлексии по СССР, то позор таким традициям. Вы пытаетесь воодушевить на изменения в рамках фреймворка который несёт вред и работает неисправно, нечего этим заниматься, нужно пересматривать фреймворк, и только это и нужно делать.
Стоит начать с того кому принадлежит RuStore, и по какой причине он вообще существует, прежде чем рассуждать о чем то духовно-полезном. И тем более делить с этой площадкой прибыль.
Мне кажется что 3 и 4 пункты как раз в Zenject есть. Это момент когда у рутового объекта будет вызван единственный Resolve. Этот объект и может иметь единственную точку входа и единственный Update() метод во всём проекте, и дальше работать уже со своим деревом просто как c C# классами.
А вот как раз 5 и 6 и не должны быть в функционале контейнера, и если в сахаре Zenject это есть, то использовать то не стоит.
Всё так, но почему в примерах статьи так много наследников от MonoBehaviour когда это обычные классы которые нуждаются в конструкторе?
Не нужно иметь под рукой сервис локатор или метод GetService, если в конструктор всё приходит, и выстроено в правильном порядке. А то что накликано в юнити мышкой, ну фиг знает, скорее всего DI нарушен многократно.
Я бы пожалуй возразил про:
Так как управлять потоком выполнения на самом деле мешает Юнити и неопределённость вызова методов у MonoBehaviour. Как раз это и корень проблемы. А например конструкторы - не важно кем выполненные, не являются такой проблемой. И не важно, выполняет их контейнер активатором или сам рантайм.
И действительно, в Zendject написано 90% бесполезного мусора, который только мешает понимать суть проблемы, тк этот сахар живёт по правилам убогого фреймворка. Но сама суть Di от этого хуже не становится, просто нужно использовать инъекцию только в конструктор и абстрактные фабрики. Для всех случаев в разработке игр этого будет достаточно. Единственный ООП кейс в котором будет неудобно, это параметризированный конструктор, где сигнатура зависит от типа. Такое скорее всего можно обойти абстрактным методом Init(x, y) у общего типа, и скрыть внутри своей фабрики, или наоборот, сделать пост-иньекцию в метод, а сами конструкторы сделать одинаковыми.
Не смотря на огрехи вашего оппонента, к вам можно применить претензию об использовании возраста как аргумента в споре.
Я бы не согласился что так проще. Это вопрос первоначального мышления и проектирования приложения. Либо мыслишь и проектируешь в древовидном графе, либо наоборот, не думая пишешь куски кода, а потом пытаешься их соеденить, и называешь это гибкость. Если всё время писать плохой код то кажется что его легче писать. И чаще всего плохой код как раз в маленьких проектах и обитает, от сюда и неправильный вывод, что сервис локаторы или синглтоны выгодны для мелких проектов.
Ой, забавно, собственно оригинальную статью и написал Марк Симан.
Кажется, научное сообщество сводится к тому что это очень близко к анти-паттерну, согласно книгам Р. Мартина и М. Симана. В первую очередь из-за ошибок времени вополнения. И конечно всё дерево связей создать один раз в compositionRoot не является возможным в более менее большом проекте, или DI будет заканчиваться именно там где начнутся new() по коду. Рано или поздно в любом проекте придется пересоздавать части графа и переиспользовать код. Не говоря уже о более мелких примитивах где напрашиваются абстрактные фабрики, знающие о скрытых зависимостях. Там где можно не писать тест на резолв, а увидеть сразу ошибку компиляции это всегда выигрыш. А если речь о большой распределённой команде, то отладка багов кривого графа связей это большая боль. Соответственно - если в смежной команде кто-то заюзал сервис локатор и выдает вам инструкции как зарегать его зависимости перед использованием кода, лучше сказать "не юзай антипаттерны" и отправить переделывать.
Самый чистый код - код который можно написать используя только иньекцию в конструктор и абстрактные фабрики. А потом уже для оптимизации написания их конструкторов можно заюзать DI контейнер.
Рефлексия - это набор еще более худших антипаттернов, так как нарушить SOLID принципы можно дуновением строки кода.
В голосовании не хватает варианта:
Статья возможно и полезна, но изложена субмурно, небрежно оформлена, пестрит ошибками и , как по мне, не отвечает на вопросы "почему?".
Сцены хороши и сейчас для изоляции физических миров или ресурсов, но я по возможности создаю их на лету. Еще в случае если приходится пользоваться лайтмапами или статическим батчингом то я использую сцены.
Я бы рекомендовал сразу в сценах организовывать переиспользование через префабы и их варианты, чтобы в сценах был минимум вариаций и менять всё можно будет в одном месте. Не вижу особого смысла иметь например уникальные канвасы в каждой сцене. К тому же в примерах через скрипты выставляются одинаковые значения для всех сцен. Чем меньше оверрайдов в сценах тем легче работа обычно.
Вообще сейчас в юнити сцена это устаревший артефакт, на который лишь завязано освещение и костыль работы с бандлами сцен. Если бы не это, сцены вообще стали бы антипаттерном имхо.
Если версия ядра старше 1.1.18100.6
Равно:
Если версия ядра меньше 1.1.18100.6