Как стать автором
Обновить
81
-2
Григорий Дядиченко @DyadichenkoGA

Master of Unity3D

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

Спасибо — поправил. Попробую в следующий раз добавить.

var attributes = type.GetCustomAttributes(typeof(UIRouteAttribute), true);

Он берёт только атрибуты этого типа. Это упрощение, чтобы не объяснять поддержку в шарпе, что может быть несколько атрибутов одного типа.

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

Первый скрин в статье.

Так не занимайтесь этим. Начните писать код без наследования и полиморфизма вообще. Прям в методе Update пишите.

Это уже уход в крайность и поэтому неинтересно обсуждать.

В программировании есть три числа 0, 1 и N. Все N равнозначны. Если вы показываете пример как надо для N=2, то он должен работать для любого N (по крайней мере в разумных пределах).

Не согласен с аналогией. Так как у нас Nmax определено выше.

Да, но там не будет 40к. Типов атаки ну 20 придумать сложно даже. Просто если мы начнём это обсуждать и дискутировать, то я уверен, что мы дойдём, что атака вообще должна быть одна. Так как она принимает таргеты и всё. И это будет лучше. Какая разница как они определяются атаке? А определение таргетов должно быть в другом месте. И может для сериализации удобнее будет енам, который идёт куда-то. Тут немного другой контекст наверное.

То есть скажем так. Ваше дополнение ценно. И моя эмоциональная реакция неверная. Минусы задевают самолюбие, как и критика. Особенно исходя из того как хабр ранжирует статьи. И я постепенно учусь это гасить (вот уже 40 статей).

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

Как говорится, я как и любой человек не идеален. И то, что статья порождает дискуссии это хорошо.

Но на тему бизнес-метрик, цикломатическая сложность, поддержка кода и т.п. Вот это уже зависит от масштаба разработки и сроков проектировки этого дела. Тут есть нюанс и контекст. Абстрактная архитектура дольше проектируется и дороже. И то что время на проектировку фичи, которая выдержит расширение на 40к строк, при том что потолок тут 1к строк теоретический не факт, что окупит затраты на поддержку. И не факт, что затраты на поддержку будут ниже, чем затраты на проектировку и разработку. И я говорил про кубик-рубика в этом контексте скорее. То есть мы можем потратить месяц на проектировку и рефакторинг к идеалу. А можем написать реализацию за один день и не встретить проблем.

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

Про SRP да согласен тупанул. Там же ответственность не инкапсулирована целиком в класс.

Он и так будет SRP нарушать. Это фасад к куче разных подсистем.

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

А так спасибо за дополнения.

Я когда-то давно читал. Может стоит перечитать конечно. Но он в цикле статей разбирал проблему, которая решается так же через композицию. Условно с тезисом, что не надо систему писать так, как кажется логичным. И "прямым ООП". И относится к ней более абстрактно.

Важно наверное сделать ремарку. А то может мой ответ может звучать как-то не так. И кто-то обижается на "адептов солида". Я ни в коем случае не принижаю вашу экспертизу. Я думаю, что вы так же, как и я сделали уже больше 100 проектов за карьеру.

Я просто не люблю разбор "что не так по солиду". Так как мне столько историй рассказывают про синглтоны те же. Что это смертный грех. Но за 100+ проектов (и три крупных с продакшенами по несколько лет и большими командами) я их там видел. И они не ломаются каждые 5 минут, как предсказывали "свидетели Солид". Я просто не люблю аргументацию "нарушается такой-то принцип солид".

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

Я же люблю говорить о бизнесовых и продуктовых недостатках. В сайд эффектах таких решений. Например дублирование иерархии. Нам придётся писать код в трёх местах, чтобы добавить фичу. Это плохо. Это лишний контракт. Его можно избежать. Но когда это 40 строк кода — это не крит. И тут не надо уходить в крайности главное, хотя велик соблазн. И я когда-то так делал в таких спорах. "Так про всё можно сказать в таком случае". Нет нельзя. Так как есть логика системы и понимание из опыта, что возможно, а что нет.

Нет, нет и еще раз нет. Я не смогу объяснить это лучше, чем сделал Эрик Липперт в своей классической серии статей https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/ и далее. Когда-нибудь я переведу их для хабра.

Стоп-стоп-стоп. Эрик Липперт говорит не про атаку. И то что это поведение никаким образом не относится к его заметке. И эту проблему как раз и решает композиция. То что описано на пол статьи, почему не надо наследовать оружие и т.п. Мышление идёт нет не от объектов игрового мира, а от процессов. Абстрактное проектирование вундерфавли я в целом не приветствую. Но это другой вопрос. Просто эта заметка вообще не про то.

Идеальной архитектуры не существуют. Давайте поговорим теперь в продуктово-бизнесовом ключе. Какие недостатки у этой архитектуры объективные? Риски и проблемы? Долгосрочные. В контексте реальной реализации. Я просто поэтому не люблю все архитектурные споры, особенно с адептами солида, так как время тратящееся на соблюдение всех мантр SOLID в среднем проекте просто не окупается.

Но изначально, я не строил идеальную архитектуру. Я просто составил задачу на композицию и решил её. Лучше, чем была изначальная схема. Вот и всё.

Итак. Спасибо за ответ, всегда интересно послушать альтернативное мнение, но пройдёмся :)

Инкапсуляция — это в контексте задачи про композицию не важно.

Двойные типы. Да согласен. Это лишнее.

Двойная проверка в фабрике. Да тут и вся эта фабрика лишняя. Она мне нужна была для примера связывания в композиции.

А вот теперь про GetAttack в AttackData и почему нет. AttackData это модель, по хорошему она не должна определять поведение. Потому что много что может не зависеть от позиции и т.п. Хотя у вас она зависит, а потом резко не зависит.

Плюс это всё выглядит красиво до реальной реализации. Так как дальше появляется ворлд менеджер, который принимает на вход атаку. И мы получаем проблему супер жирного контроллера. Так как менеджер мира знает, как собрать данные о целях для конкретной атаки. И теперь у нас игрок собирает цели и атакует их. Это не совсем верная логика системы. И у нас SRP нарушает менеджер мира.

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

И логика этого проста. Атака сама реализует логику своей обработки, так как это её ответственность.

Внутри метода Attackобращение к WorldManager выглядит крайне плохо, хреново тестируется и нарушает SRP и ISP (SOLID). 

То есть это чушь. Так как вызов WorldManager в атаке — не нарушает сингл респонсибилити. Так как наш запрос не меняет никакого состояния волрд менеджера. У нас есть стейт, мы из него запрашиваем данные для реализации нашей функциональности. Вот и всё. Там не усложняется никак тестирование. Так как волд менеджеру вообще должно плевать кто его вызывает. Он не в курсе. Если про тестирование атаки, чтобы подсунуть в неё мок менеджера. А для чего и зачем? В миниатюрный класс в 10 строк пихать юнит тест. Без мок мира целиком (то есть не интеграционный). А для чего?

Передавать его в качестве параметра метода тоже нет никакого смысла. Для сингл таргет цели мы передадим в конструктор нашей атаки конкретную цель допустим. И это будет в разы удобнее.

Последний блок кода в целом странный, но мне кажется вы просто запутались. Так как там что-то странное в AOEAttack.

Пока написал понял что деление наXXXAttack иXXXAttackData не нужно. В целом у вас только одна точка где вам нужен полиморфизм - GetDamagable. Для полиморфизма в одном месте вам не надо городить две параллельные иерархии. Параллельные иерархии это вообще code smell.

Оно не обязательно было бы без оптимизаций и специфики. И вопрос подхода к архитектуре. Структура тут нужна для оптимизации. Так как атаки — это часто аллоцируемые команды. Которые поэтому нехорошо делать в виде классов. А данные (а точнее поля) расширять без классов неудобно. Это по сути про отличие объектов поведения, и объектов данных.

Можно было бы определять в XXXAttackData без XXXAttack без этой оптимизации. Если бы не ещё одно но. Разные поведения могут опираться на общие данные. Это в конкретной реализации получаются параллельные иерархии. А в реальной игре иерархия данных вполне может отличаться от иерархии объектов поведения. Опять-таки для удобства.

Да, норм улучшение. Но есть два нюанса.

Первое, что такие маленькие объекты пойдут в малую кучу, поэтому это не так критично. Юнити вроде как исправили то, что малой кучи в юнити не было.

А во вторых в шарпе нет наследования структур. Поэтому возникает вопрос «как расширять число полей». Композиция интерфейсов и адаптер. Ну может быть, но не уверен, что это будет сильно лучше.

Плюс основной вопрос. А зачем это оптимизировать? AOEAttack — это структура. Так как её аллоцировать мы будем часто. А AttackData чаще всего на запуске приложения и всё. Так как это данные оружия. Или при выпадении предмета забирая данные из базы. Или в момент загрузки юзера, чтобы посмотреть инвентарь. То есть вряд ли тут аллокации будут когда-то создавать фризы.

И жертвовать ради этого удобным расширением числа полей — не уверен, что стоит.

Нет, я не пользуюсь ECS. И как следствие не буду писать о том, в чем я не разбираюсь.

Это видимо кеш. У меня уже ок, ща протестил. Но если у кого вдруг ещё так лагает, то вот отдельно https://t.me/+ZypFCP_rxic4NTEy

Да, спасибо. Исправил. Видимо с утра запутался в своих ссылках и с поста забрал. Но видос там был тоже интересный :)

В целом я занимаюсь разработкой можно сказать, что AR&VR, стендовых проектов и т.п. https://noxatra.ru

Для корпораций. Делали много всякого со сбером, награду за лучшее решение в нефтегазовой промышленности получили с ГПН за VR телепортацию и так далее. Но да. Тут может быть расхождение в терминологиях из-за того что с гос. закупками я не работаю.

Но в любом случае интересно почитать и узнать новое. Это хорошо, когда статья создаёт поле для дискуссии на мой взгляд.

Думаю вы правы про VC. Просто я обычно пишу другой характер статей и в основном сюда, а такой материал на vc лучше бы подошёл наверное.

Я работаю в коммерческом секторе. Но спасибо за уточнение. Не знал таких терминологических нюансов.

Согласен. Звучит неплохо. Но всё равно вызовет вопросы что это. Так же как и "препродакшен". Если вносить это в смету. Но много у кого в сметах просто ТЗ.

Да, спасибо. Отличное дополнение :)

Я мало с жирными в плане звука проектами работал. Ну и по остальным пунктам согласен.

Ща исправлю. 200МБ, если в настройки не лезть телефона. С аойс 13 можно поставить что любой размер будет качаться.


Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность