Pull to refresh

Comments 17

PinnedPinned comments

Ну, что же. Очевидное разъяснение про MVC в итоге не понравилось. Псевдо-учителя учат тому, что не знают сами для чего нужно, в итоге 10-кратный оверхед. Людей, которые это ценят меньше. Бред про коде стайл, да еще очевидно неверный - плюсуют. Здесь серьезно есть специалисты? Думаю, нет. За, сим, откланиваюсь, пока тут не появятся думающие люди, разбирающиеся хоть немного в профессии программиста, а фрики мне как то поднадоели.

Кто же все таки захочет задать вопрос или прокомментировать - прошу на мой канал.

Оно всё конечно здорово, но в вашем примере качество кода сперва стоит улучшить, исправив readability косяки.

Но сперва по существу вопроса: MVC практически не заменимая штука, когда над игрой работает дев в паре с тех. артистом. В таком случае как раз прогер делает большую часть логики в MC, пока тех. артист пилит всякие красивости для V. Если бы они работали в одном общем классе то это была бы во-первых боль при работе с системой контроля версий, а во-вторых код связанный с визуалом имеет свойство быть очень объемным и игровая логика может в нём просто потонуть, ухудшая читабельность.

А теперь по читабельности примера. Вы уж простите но меня триггерит, когда в статье про паттерны и архитектуру сам код-пример нуждается в рефакторинге х)

1) Проверка на false

if (IsDoneBinding(BindingBehavior[i].Name) == false)
Не надо так ? Давайте использовать цивилизованный

if (!IsDoneBinding(BindingBehavior[i].Name))

2) Кеширование локальной переменной
Нет нужды несколько раз вызывать BindingBehavior[i].Name в пределах одной итерации цикла. Во-первых это создает усложняющую чтение визуальную нагрузку, а во-вторых чуть-чуть добавляет работы процессору (хоть извлечение по индексу это и очень быстрая операция). Лучше один раз закешировать это в локальную переменную и пользоваться ей.

var behaviorName = BindingBehavior[i].Name;

3) Разбиение методов на логические части пустыми строками

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

4) Диагональный ветвистый код

Если у нас в коде появляется if, вложенный в if, вложенный в цикл, вложенный в if, то что-то явно пошло не так. Человеческому мозгу проще воспринимать линейный код чем пытаться отследить все ветви кучи ifов. Как rule of a thumb, я стараюсь держать индентацию в пределах 2х, максимум 3х табов. В этом хорошо помогает на мой взгляд один из самых недооцененных readability паттернов early return, суть которого заключается в том что мы вместо расписывания всех возможных ветвей кода просто выходим из метода раньше времени (или уходим на следующую итерацию цикла).

Для наглядности всего перечисленного вот исправленный метод Bind():

https://pastebin.com/mSSMm2eL

PS А еще у меня подозрение что этот метод вообще ничего особо делать не должен, если у нас Related == null (но я не знаю что у вас происходит в IsDoneBinding и AddDoneBinding, которые вы почему-то в пример не включили. Но если в них переменной Related значения отличные от null не присваиваются, тогда код можно упростить еще сильнее: https://pastebin.com/79qpcvPX )

Вы не правы по всем пунктам, я пояснять не буду. Но прежде, чем придираться к мелочам, начните правильно использовать MVC. Захотите от меня ответов - спросите уважительнее.

тех. артист пилит всякие красивости для V

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

Серьезно? артист пишет такой код? кого вы пытаетесь насмешить, и тем самым оправдать применение MVC ради самого применения?

Может для декомпозиции кода, нужно не MVC использовать? И не только коде стайл использовать популярный, который просто кричит глупостями?

Если у нас в коде появляется if, вложенный в if, вложенный в цикл, вложенный в if, то что-то явно пошло не так.

Так как это настолько часто возникающая несуразица, я лишь спрошу где источник этого несерьезного утверждения? Вы думаете, заменив это на return вы сделали лучше? Тогда я посоветую вам использовать goto они позволяют убрать больше if :)

P.S. Вы просто думайте, когда насмотревшись по ютубу всяких умников, начинаете учить других ... а то, что это советы от умников - аж сквозит ...

Так как это настолько часто возникающая несуразица, я лишь спрошу где источник этого несерьезного утверждения? Вы думаете, заменив это на return вы сделали лучше?

Настоятельно рекомендую открыть линтер.

ну договаривайте ... тогда и поговорим ... когда, же мне начинают говорить, полунамеками, не утруждая себя никаким аргументированным тезисом, да еще ad hominem - о чем говорить?

P.S. А о качестве кода я лучше знаю, чем любая автоматизированная шняга ... скорее будут вопросы к её разработчикам.

Мои источники - 5 лет коммерческого опыта, из которых полтора года в Британском юникорне, в котором меня на ревью за такое качество кода как минимум попросили бы объясниться и отправили переписывать)


Вы говорите про неуважение, но я в комментарии ни слова не сказал про вас. Неумение отличать критику кода от критики написавшего его человека это распространённая проблема, которая может привести к трудностям в командной работе. Решается транспарентностью в коллективе и прокачкой emotional intelligence.

Всё что написано выше (как и предыдущий мой оригинальный коммент) написано не столько для вас, сколько для юнити-новичков, которые могут зайти в эту статью и долистать до комментов, посему я достаточно подробно расписал довольно очевидные для более опытного разработчика вещи.

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

Мои источники - 5 лет коммерческого опыта

Вы сами понимаете, что этого мало? Что как минимум в раза 4 это меньше моего? Я же имел как минимум авторитетные источники, хотя бы банду 4 назвали бы и ссылку, где они такое говорили? Что это за манера такая, не зная оппонента думать, что он знает меньше вас?

Вот именно, за мозги новичков мы тут и боремся да? Ну, ок пусть так ...

Отвечать вам надо, почему вы думаете, что все что вы написали вообще имеет смысл обсуждать? Зачем мне с вами обсуждать ваши глупости? Ну выучились вы где-то не так ... мне что до этого?

Вам объяснить и так надо ...

  1. Почему вы позволили себе использовать переменную var в строготипизированном языке?

  2. Почему вы бесполезно ввели лишнею переменную behaviorName

  3. if (IsDoneBinding(BindingBehavior[i].Name) == false) - нет именно так и надо, почему вы предпочитаете "усложняющую чтение визуальную нагрузку" аналог ?

  4. Почему вы позволяете себе return в методе ничего не возвращающем, почему не используете goto?

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

И нет, вы позволили себе - учить меня тому, чего я не просил! Учить тому, что как минимум спорная практика, да спорная! Кто вам скажет, если не такие как я ... больше читайте теории, в голове будет еще больше каши. Вы мне еще расскажите как скобки ставить ...

И все это при том, что статья совершенно о другом. Вы утрудили себя хотя бы прочитать предыдущую статью, разобрать в этой и понять когда нужен MVC, и как его учат использовать? А ведь учили там тоже мол учитель в МФТИ с опытом коммерческой разработки ...

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

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

Давайте начнем с того что написано по-существу:

Почему вы позволили себе использовать переменную var в строготипизированном языке?

Ничего страшного, строгая типизация никуда не денется, нужный тип выставится компилятором на этапе сборки. Вы даже можете получить все те же complie time errors как если бы тип переменной был объявлен явно (Источник https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var)
С другой стороны, использование var избавит нас от необходимости изменять объявление переменной behaviorName если тип BindingBehavior[i].Name изменится на другой. Бонусом мы также получаем более аккуратный код при объявлении нескольких переменных подряд, пример:
// Зачем два раза писать имя класса? Визуальный мусор

// Индентация до имени везде разная - создает friction при чтении кода

Foo foo = new Foo();

List<Foo> fooList = new List<Foo>();

bool isFooSpawned = foo.IsSpawned;

Против:

var foo = new Foo();

var fooList = new List<Foo>();

var isFooSpawned = foo.IsSpawned;

Второй вариант читается на мой взгляд гораздо легче. Я допускаю что в некоторых компаниях предпочитают так не делать, но мне такие компании не встречались.

Почему вы бесполезно ввели лишнею переменную behaviorName

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

if (IsDoneBinding(BindingBehavior[i].Name) == false) - нет именно так и надо, почему вы предпочитаете "усложняющую чтение визуальную нагрузку" аналог ?

Это наверное самое субъективное из всего списка. Вариант с явным сравнением с false сильнее визуально нагружает, на мой взгляд. Я допускаю что вы можете думать иначе и это ваше право, но я не понимаю как
if (condition1 == true && condition2 == false || condition3 == true)

может быть более читабельно чем

if (condition1 && !condition2 || condition3)

Почему вы позволяете себе return в методе ничего не возвращающем, почему не используете goto?

Я не использую goto потому что он избыточен для данной ситуации (да и вообще юзать goto это так себе практика), более того, зачем юзать goto если в C# есть ключевое слово специально для нашей ситуации? Смотрим: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/statements/jump-statements#the-return-statement

The return statement terminates execution of the function in which it appears and returns control and the function's result, if any, to the caller.

As the preceding example shows, you typically use the return statement without expression to terminate a function member early.

Вот и ответ на ваш вопрос "почему вы себе позволяете": потому что это литерали то, ради чего это слово было добавлено в язык.

Вы также справедливо заметили, что я мало что написал по поводу самой статьи. Я скажу как читатель хабра что мне не нравится, когда в prerequisites для понимания статьи входит просмотр видео на ютубе. Моё ИМХО что статья должна быть самодостаточной, но без просмотра видео что эта, что прошлая статья больше запутывают чем объясняют. Но в этом конкретном случае я посмотрел видео, о которых идёт речь, и моё мнение что вариант в принципе рабочий в некоторых ситуациях. Хочется только спросить в чём преимущество такого подхода по сравнению с другими методами для решения такой проблемы? Мне кажется используя тот же Zenject решить проблему можно было бы гораздо меньшими усилиями.

Теперь давайте к весёлой части)

Вы сами понимаете, что этого мало? Что как минимум в раза 4 это меньше моего?

Да, я понимаю что 5 лет это меньше чем 20. А ещё я понимаю что это имеет абсолютно нулевое отношение к поставленным вопросам. Аргумент "я прав потому что у меня 20 лет опыта" это обычный аргумент от авторитета, являющийся подвидом ad hominem на который вы жаловались в соседнем комменте.

Во всех компаниях где я работал всегда поощрялось когда начинающие ставят под вопрос действия синьоров. В 9 из 10 случаев синьор окажется прав, объяснит новичку почему он прав, новичок за счет этого поднимет свой технический навык, что хорошо для компании. В 1 из 10 случае синьор окажется неправ (нет людей которые не ошибаются) и код попадет в проект только после исправлений, что также хорошо для компании. Win-win. А за аргументацию вида "делаем так потому что у меня N лет стажа" синьора ждал бы как минимум разговор с HR.

Что это за манера такая, не зная оппонента думать, что он знает меньше вас?

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

И нет, вы позволили себе - учить меня тому, чего я не просил!

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

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

Мне кажется тут у нас есть идеологическое разногласие. Поправьте меня если я ошибаюсь, но мне кажется что стиль кода и readability для вас является чем-то второстепенным.

Я для пояснения своей позиции вернусь к базовому вопросу: в чём заключается суть работы программиста, применительно к геймдеву? По моему убеждению, все сводится к тому что мы должны написать продукт, который приносит стейкхолдеру максимум $$$, при минимальных затратах $$$ самого стейкхолдера. Для программиста достижение этой цели держится на трех столпах:

1) Умение эффективно коммуницировать как с техническими, так и с нетехническими коллегами.

2) Умение создать удобную, адекватную, расширяемую архитектуру.

3) Умение писать код чисто и понятным/принятым в компании стилем.

Убери один столп - и стейкхолдер начнет терять $$$.


У вас чистый код, но плохая архитектура? При добавлении новой фичи придется муторно/долго её подключать, и стейкхолдер потеряет $$$.

У вас хорошая архитектура, но код стайл плохой/не соблюдается? При ротации новичка на проект он будет первые несколько месяцев с головной болью плутать в куче вложенных ifов и ветвящихся методов, и стейкхолдер потеряет $$$.

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

Со всех сторон хороший фидбек, и программист получает заслуженный рейз $ :)

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

На мой взгляд вы ведете себя очень не профессионально для человека с вашим стажем.

Ох, пристыдил то как ... но единственной моей задачей было сбить спесь, и заставить не писать так безапелляционно, таким как вы ... Теперь, когда вы еще кому ни будь напишите про коде стайл, пишите именно так (сделаю вам win):

  1. "вариант читается на мой взгляд гораздо легче. Я допускаю что в некоторых компаниях предпочитают так не делать ..."

    • Да, я в такой работаю ..

    • "Зачем два раза писать имя класса? Визуальный мусор " - это глупость в том месте тип не написан, во время рефакторинга необходимо многое править в зависимости от типа, наличие var - очень сильно замедляет рефакторинг, а тут я могу по праву сослаться на опыт :)

  2. "Она не лишняя, её предназначение - удобочитаемость. "

    • у Фаулера почитайте про временную переменную - это признак кода с душком , а вы мне предложили её ввести. Отличие опытного программиста, это не подаваться на провокации :) И нет удобочитаемостью вы пожертвовали столько раз, что это уже не аргумент

    • Дальше откройте, книгу "Балена Ф. и Димауро Д. - Современная практика программирования на Microsoft Visual Basic и Visual C# - 2006"

    • Но это (Фаулер) входит в противоречие с правилом 12.25 - но в моем случае и не было, как минимум длиной вложенности

  3. "Это наверное самое субъективное из всего списка. Вариант с явным сравнением с false сильнее визуально нагружает, на мой взгляд. "

    • Как не странно, но правило 18.9 за ваш подход. Но, в случае конкретно этого случая - там не простое сравнение с переменной в моем случае (вы то ввели бесполезную), поэтому, тут мне надо писать , имхо, знак ! плохо виден в отличие от единообразного сравнения с == flase / == true (да, и слова "сильнее визуально нагружает" - надо воспринимать так, что для этого то я это и делал)

  4. О return - Правило 14.16 Единственная точка выхода ... тут вам надо просто подучить мат. часть

  5. Так же у Фаулера читайте про декомпозицию и консалидацию условных выражений, для вас будет полезно, не будете делать больше такие ошибки, но т.к. вы не ответили на это изначально, будем думать что поняли свои ошибки ...

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

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

Можете, пожалуйста, дать более конкретную ссылку на Фаулера и его мнение о временных переменных?

Теперь мне приходит в голову, что переменная thisAmount стала избыточной. Ей присваивается результат each.charge, который впоследствии не изменяется ..

37 стр.

Мне кажется используя тот же Zenject решить проблему можно было бы гораздо меньшими усилиями.

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

Но давайте так, я уеду на 2 недели, а вы реализуйте биндинг на Zenject  - вы же это предлагали? А я приеду почитаю, покритикую, сделаем win-win :) ?

Да, еще мини урок для любителей схлопывать условия, типа

if (Related != null && !IsDoneBinding(behaviorName))

не делайте так никогда. Код должен быть удобен для рефакторинга, условия это одно из главного, что часто меняется. Понятно когда условие вложено в условие это аналог && но во-первых, это становится не так при наличии else. А во-вторых, и в главных, условия должны быть атомарными, относится к одного рода проверке. Здесь они о разном Related != null - это есть ли партнер для связывания, а IsDoneBinding - был ли биндинг сделан.

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

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

Чем ваш первый пример цивилизованнее, кроме того, что он короче, и что так проще допустить ошибку, не заметив отрицание?

UFO landed and left these words here

Ну, и раз зашла такая тема. Некоторые наблюдения.

2 курс. Без разницы как писать код, лишь бы работал ...

5 курс. Начинаешь верить в какую-то идеализацию. Вырабатываешь свои взгляды на стиль ...

1-5 года работы. Смотря как повезет, если такие же молодые как ты - то вы начинаете заниматься ерундой - стандартизировать стиль в компании. Если нет, не понимаешь почему другие мамонты не хотят менять свой стиль.

5-10 лет. Отстаешь от других и просто кодишь сам в том стиле который нравится тебе.

10-15 лет. Не позволяешь другим себя переучивать. Идешь лишь на мелкие уступки.

16-17 лет. Меньше пустозвонства - чтобы не поссорится о стиле кодинга не говорим, моветон - аналогично обсуждать политику, или зарплату.

17-18 лет. пофиг какой стиль, читать можешь что угодно, но если скобки стоят не так как нужно - не понятно что написано.

19-20 лет. увольнять если используешь пробелы вместо табов - кажется правильная идея :)

В MVVM главное - это забиндить поля vm к view, а не наоборот. Делается это для упрощения логики и независимости компонентов и ивентов. А View смысл биндить есть только если вьюха на xaml. Легче использовать тот же unityevent

Ну, что же. Очевидное разъяснение про MVC в итоге не понравилось. Псевдо-учителя учат тому, что не знают сами для чего нужно, в итоге 10-кратный оверхед. Людей, которые это ценят меньше. Бред про коде стайл, да еще очевидно неверный - плюсуют. Здесь серьезно есть специалисты? Думаю, нет. За, сим, откланиваюсь, пока тут не появятся думающие люди, разбирающиеся хоть немного в профессии программиста, а фрики мне как то поднадоели.

Кто же все таки захочет задать вопрос или прокомментировать - прошу на мой канал.

Sign up to leave a comment.

Articles