Как стать автором
Обновить

Прочитал книгу по C# или что написал Рома Сакутин

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров27K

Предыстория

Я познакомился с Романом, когда он публиковал на YouTube видео, в которых критиковал качество кода, написанного другими разработчиками, и создавал образ эксперта, который знает, как писать чистый и аккуратный код. На самом деле Роман действительно обладает такими знаниями, но то, как он их применяет, вызывает вопросы. Многие люди последовали за ним, стали использовать практики, которые он пропагандировал, и в целом доверяли его мнению. Затем Роман создал свою онлайн-школу для программистов, специализирующихся на C#. Я даже приобрёл его курс. Тогда я понял, что он учит не намного лучше, чем другие школы. Сейчас его курсы доступны для бесплатного ознакомления. Изучив их, мы увидим, что в его курсе реализация FSM (конечного автомата) слишком упрощена и не готова к использованию в реальных проектах.

О чем я тут раскидал буквы

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

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

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

В основном мы будем говорить не о том, как написана книга, а о том, какие вредные советы она может давать. А в конце обсудим, насколько полезна эта книга в мире, где есть такие издания, как:

  • Clean Code by Robert C. Martin. (Uncle Bob)

  • Clean Architecture by Robert C. Martin. (Uncle Bob)

  • CLR via C# by Jeffrey Richter

Вредные советы

Я буду приводить вредные советы по мере их появления в книге и объяснять, почему они вредны.

  1. Перегрузка операторов для кастомных типов в C#

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

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

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

    Это будет выглядеть следующим образом:

    public struct Army
    {
        private readonly int _damage;
        
        public int Amount { get; }
    
        public Army(int amount, int damage)
        {
            Amount = amount;
            _damage = damage;
        }
    
        public static bool operator <(Army a, Army b)
        {
            return a.GetPower() < b.GetPower();
        }
      
        public static bool operator >(Army a, Army b)
        {
            return a.GetPower() > b.GetPower();
        }
    
        private int GetPower() => _damage * Amount;
    }

    И вроде бы все хорошо, но это только пока мы смотрим на то, как этот объект устроен, а стоит нам абстрагироваться и забыть про то, что мы перегрузили операторы <> то сразу теряется нить того, что они сравнивают именно общую силу, а не количество.

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

  2. Засорение аргументами
    Далее приводится пример того, как "можно" расширять код без риска его поломки при внесении изменений.

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

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

    public void Apply();
    public void Apply(int port = 80);

    Этот вариант имеет существенный недостаток: метод может начать принимать четыре, десять или двадцать аргументов, что противоречит принципам «Чистого кода» и приводит к созданию огромного и сложного метода, который берёт на себя слишком много задач.

    Однако есть способ решить эту проблему и не нарушить работу людей, которые используют старый метод. Мы можем использовать механизм перегрузки метода.

    [Obsolete("It is legacy method, please use Apply(int port)")
    public void Apply();
    
    public void Apply(int port);

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

  3. Правила не передавай/возвращай null

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

    © Роман Сакутин "C# Для Начинающих на практике"

    В данном случае, мы в принципе нарушаем принципы "Чистого кода".

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

    ...

    Возвращая null , мы фактически создаем для себя лишнюю работу, а для вызывающей стороны - лишние проблемы.

    © Robert C. Martin "Clean Code"

    То же самое касается и принимающей стороны. Зачем нам дополнительная проверка в алгоритме программы? И почему мы передаём null?

    Причина проста: однажды мы поленились сделать всё правильно, и теперь всегда будем писать лишний код.

    Можно возразить, что в приведённом в книге примере проверка будет выполнена только внутри метода. Вы правы, но добавление проверки внутри метода вступает в противоречие с принципами «чистого кода». Наш метод начинает изменять своё состояние в зависимости от определённого флага (в данном случае это будет сравнение аргумента на null), что нарушает правило об одной операции.

    Функция должна выполнять только одну операцию. Она должна выполнять ее хорошо. И ничего другого она делать не должна.

    © Robert C. Martin "Clean Code"

Вендинговый автомат

Эта часть книги по всей своей сути полностью повторяет часть книги Чистый Код, где Роберт Мартин показывал, как он перерабатывал свой и чужой код так, что бы этот код становился лаконичным и читаемым.

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

Действительно полезная информация

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

К таким вещам относятся:

  • Принципы S.O.L.I.D и то, как мы их используем и почему мы их используем.

  • Framework Roslyn - полезное API для написания собственных анализаторов кода.

  • Числа Фибоначчи - преведена целая глава работы с этими числами, что я считаю полезным для начинающих.

  • Работа с Reflection, но тут важно уточнить, что опять же, Роман не сообщат, что чрезмерное использование рефлексии, (может привести) приведет к снижению производительности.

Заключение

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

Исходя из заголовка книги "C# Для Начинающих На Практике", я отношусь к тексту этой книги более легко, если название было что-то типа "C# Для Заканчивающих На Практике".
Но это не дает права на те вредные советы, которые были приведены в книге!

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

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

По отношению к Рихтеру, то тут все еще проще, Рихтер пишет о том, как C# работает, а Роман пишет о том, что есть if и оператор == и исходя из этих данных, выгоднее один раз купить CLR via C# и если не прочитать его, то обращаться к нему в спорных моментах, что бы понимать, как язык на котором вы общаетесь с машиной, будет работать.

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

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+21
Комментарии80

Публикации

Истории

Работа

Ближайшие события

Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область