Всё, что вы хотели узнать о рефакторинге, но боялись спросить

    Господа, рад представить вам свой новый проект — Refactoring.guru.

    Сайт представляет собой каталог запахов грязного кода и, собственно, самих приёмов рефакторинга. В двух словах — это как книга Мартина Фаулера, но лучше. А именно:

    • Весь контент доступен на русском языке. Я старался делать описания как можно более живыми, чтобы избавиться от чувства унылости и скуки, которое возникает при чтении любой переводной книги о рефакторинге.
    • Все примеры подаются на Java и PHP. Другие языки обязательно будут добавляться со временем, но я пока затрудняюсь решить, каким будет следующий, можете предлагать в комментах.
    • Всё везде перелинковано. Рефакторинги сгруппированы по предназначениям и связям.


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

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

    Буду рад всем отзывам и пожеланиям! (а также лайкам и твитам)

    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 57
    • +3
      Хороший портал, к сожалению нашел пару ссылок, с объяснением паттернов на аналогичный англоязычный ресурс.
      Конечно, хотелось бы не париться в сложностях перевода и почитать на родном. Но, думаю, скоро автор портала дополнит этот материал на своём ресурсе.

      А картинки — вообще прелесть.

      Что можно добавить: паттерны реализации на разных языках программирования.
      • +4
        В дополнение к вышесказанному: очень понравилась интерактивность рефакторинга. Все разложенно по полочкам.
        еще раз, хочу поблагодарить за полезный ресурс.
      • +11
        Javascript должен быть следующим добавленным языком.
        • +9
          Вы ведь планируете расширять это на другие языки? Создайте репозиторий, да принимайте пулл-реквесты от желающих помочь — такие, я думаю, найдутся.
          • +2
            Было бы здорово иметь возможность скачать материалы в формате электронных книг (.mobi, ...)
            • 0
              тогда вся фишка интерактивности исчезнет
              • 0
                Для интерактивности читаем портал. Для чтения больших статей во время поездки в метро, мобильная offline версия самое оно, имхо.
              • +5
                Не проще ли тогда купить книгу по рефакторингу?
              • +5
                Сам по себе сайт очень красивый и приятный. Воздушный как зефир. Жаль что нет Javascript…
                • +1
                  С JS проблема в том, что там актуальны наверное только половина рефакторингов, т.к. нет настоящей поддержки ООП, с наследованием областями видимости и другими фичами. Но я подумаю, что можно сделать. Как минимум первые главы точно можно будет перевести на JS.
                  • +1
                    Думаю проблема не в JS, а в том что Фаулеровский рафакторинг написан под java и иже с ней. Естесвенно часть рефакторингов универсальна, а часть специфична для языка (группы языков).
                    • –4
                      Если использовать CoffeScript, то появляются классы и практически ООП.
                      • 0
                        ES6 вам в помошь
                        • +2
                          А ООП обязателен для рефакторинга, что ли? Речь должна идти не о том, чтобы портировать имеющиеся главы на JS, а о том, чтобы добавить приемы рефакторинга, актуальные для этого языка. Всё-таки он сильно отличается от Java и PHP.
                          • +1
                            > нет настоящей поддержки ООП
                            ООП это парадигма, а не обязательное присутствие в языке классов или ещё чего другого. Хотите сказать, что в JS нет поддержки инкапсуляции, полиморфизма или наследования? Всё это есть, только не в том виде, в которым вы привыкли видеть (class B extends A, хотя и этот сахарок уже добавили в ES6, как написали выше).

                            В Си тоже нет, с вашей точки зрения, ни наследования, ни областей видимости (я так понимаю, подразумевались пространства имён, namespaces) и, тем не менее, там есть наборы библиотек (самый известный пример это, наверное, en.wikipedia.org/wiki/GLib на базе GObject), которые написаны с применением ОО парадигмы.
                            • 0
                              Просто люди привыкли, что OOP — это class based концепция, а альтернативные (прототипные как в языке self ) им непривычны
                        • +2
                          Прекрасный портал и «интерактивные примеры с объяснениями» покорили.

                          И да — я голосую за javascript.
                        • 0
                          Пользуясь случаем задам автору и читателям вопрос. Если есть стастические анализаторы кода, почему бы не сделать автоматический рефакторер?

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

                          Критерий оптимизации — соответствие формальным критериям в книжке и уменьшающийся объём кода.
                          • +2
                            Под «автоматическим» вы это имеете ввиду?

                            image
                            • 0
                              Да, именно так :)
                              Примеры похожих реализованных кнопок — GPS-навигаторы, поисковые сервера, пицца на заказ и прочие усовершенствования в жизни.
                            • 0
                              посмотрите на продукты jetbrains. Там автоматизированный рефакторинг. Полностью автоматический вряд ли можно сделать — кто будет придумывать идентификаторы для методов и т.д.
                              • –1
                                Там рефакторинг «вручную», но с правилами, которые могут лечь в основу рефакторинга автоматического. А идентификаторы — да, генерить на основе имеющихся, типа FooSubmethod1()
                                • +2
                                  > генерить на основе имеющихся, типа FooSubmethod1()

                                  Попробуйте обфускатор
                            • +1
                              Вроде бы знаешь один язык, разберешься и в остальных… Но любителей Яваскрипта это, кажется, не касается.

                              И так зря были потрачены некоторые на то чтобы делать по два по-сути одинаковых примера. Если отличия серьёзные, примеры на разных языках могут быть оправданы, но три просмотренных рефакторинга пока что говорят об обратном.

                              P.S. Автор молодец, и сайт симпатишный.
                              • +1
                                Оно-то так, но каждый человек желает «ещё больше» комфорта. Ну и некоторые моменты всё же отличаются, их очень мало, но они есть.
                              • 0
                                Оффтоп.

                                Не очень люблю крупный шрифт (дело вкуса), игралась с масштабом и в 90% получила не слишком приятный «наезд» подчеркивания:

                                image

                                Маньяк внутри полез смотреть верстку и обнаружил:

                                p a { text-decoration: none; background-image: -webkit-linear-gradient(top,#fff 50%,#3a3a3c 50%); background-image: linear-gradient(to bottom,#fff 50%,#3a3a3c 50%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ff3a3a3c', GradientType=0); background-size: 2px 2px; background-position: 0 1em; }

                                Почему именно так? Любопытно, есть ли преимущество в таком способе обычного подчеркивания? (с кастомным все понятно).
                                • 0
                                  Насколько я понимаю, так получается, всё-таки, не обычное подчёркивание, а тонкое, однопиксельное. Сравните:

                                  • 0
                                    Да, но между использованием text-decoration и background еще есть более простой border:

                                    • 0
                                      Border, как правильно, отображает черту на несколько пикселей ниже, чем при обычном подчёркивании.
                                      • +1
                                        В итоге, не сработала часть вашей картинки по поводу подчёркивания:
                                        image
                                  • 0
                                    Вот здесь описаны и причины и техника: medium.com/designing-medium/crafting-link-underlines-on-medium-7c03a9274f9
                                    • 0
                                      Большое спасибо! Чего-то такого и ожидала.

                                      А по поводу «наезда» при 90% масштабе, заменила background-position: 0 1em; на background-position: 0 23px; и все стало смотреться идеально.
                                  • +1
                                    Классный сайт, все очень понравилось. Чуть-чуть с величиной заголовков автор переборщил на мой взгляд, а так все очень здорово. Дизайн немного похож на англоязычный sourcemaking.com, наверное, он служил примером.
                                    Еще раз спасибо :)
                                    • +4
                                      Очень было бы интересно взглянуть на питоновские примеры.
                                      • +4
                                        Я бы даж поспособствовал их написанию :)
                                        • 0
                                          Если есть желание и возможность, можно помочь с переводом примеров. Вот репозиторий с текущими примерами: github.com/shvetsgroup/refactoring.guru-examples

                                          Буду рад пулл-реквестам! :)
                                      • +1
                                        У Вас ошибка в живом примере на Java refactoring.guru/replace-method-with-method-object:
                                        В шаге 5 отсутствует замена локальных переменных приватным полями.
                                        Хорошо бы добавить кнопку «Сообщить об ошибке».
                                        А так сайт отличный, однозначно в избранное!
                                        • 0
                                          Большое спасибо, исправил этот момент. Кстати, там если справа на странице зеленая плашка, ведущая на под-сайт поддержки, вот там можно оставлять сообщения об ошибках.
                                        • +1
                                          Мартин Фаулер в своей книге уделяет большое внимание юнит тестам. Если код не покрыт юнит тестами, то рефакторинг такого кода становится опасным.
                                          Хорошо бы упомянуть как-то этот момент на Вашем сайте, допустим в интерактивных примерах можно добавить шаг с запуском юнит тестов, и т.п.
                                          • +3
                                            neochief с меня печеньки, куда выслать?
                                            • –2
                                              Страницы грузятся очень медленно, вплоть до подвисания всего браузера на несколько секунд. Скорее всего из-за этих никому не нужных социальных кнопок.
                                              • 0
                                                хабраэффект же
                                              • 0
                                                В этом примере на выходе получаем код, в котором метод описан внутри тела конструктора и при этом виден из другого класса. Если просмотреть пример до конца, то после того как рефакторинг закончен начинает творится что-то странное ( Ну или так отработало показать изменения.
                                                • 0
                                                  Спасибо, это жирная бажина, которую я только что исправил.
                                                • 0
                                                  Отлично, спасибо!
                                                  • 0
                                                    В живом примере с PHP ошибка на последнем шаге.
                                                    вместо

                                                    return outstanding;
                                                    


                                                    должно быть

                                                    return $outstanding;
                                                    
                                                  • 0
                                                    Спасибо огромное, сайт просто великолепный, интерактивные примеры сделаны очень круто. Был бы рад увидеть среди них примеры на python.
                                                    Ни в коем случае не переделывайте дизайн — он идеален.
                                                    • 0
                                                      Всё также. С ходе примера метод compute оказывается внутри тела конструктора. Хотя должен быть отдельным методом в классе.
                                                      class Gamma {
                                                        private final Account _account;
                                                        private int importantValue1;
                                                        private int importantValue2;
                                                        private int importantValue3;
                                                        private int inputVal;
                                                        private int quantity;
                                                        private int yearToDate;
                                                        public Gamma(Account source, int inputValArg, int quantityArg, int yearToDateArg) {
                                                          _account = source;
                                                          inputVal = inputValArg;
                                                          quantity = quantityArg;
                                                          yearToDate = yearToDateArg;
                                                          public int compute() {
                                                            int importantValue1 = (inputVal * quantity) _account.delta()();
                                                            int importantValue2 = (inputVal * yearToDate) + 100;
                                                            if ((yearToDate - importantValue1) > 100) {
                                                              importantValue2 -= 20;
                                                            }
                                                            int importantValue3 = importantValue2 * 7;
                                                            // и так далее...
                                                            return importantValue3 - 2 * importantValue1;
                                                          }
                                                        } 
                                                      } 
                                                      
                                                      • 0
                                                        Это кеш. Стоит почистить и все появится.
                                                      • 0
                                                        refactoring.guru/replace-temp-with-query
                                                        результирующий код может получить дополнительную нагрузку за счёт вызова нового метода. Однако, в наше время быстрых процессоров и хороших компиляторов, такая нагрузка вряд ли будет заметна

                                                        больше всего в книжках про красивые рефакторинги смущают такие моменты. в теории, да, может быть, а на деле? рядом с примерами «до» и «после» было бы крайне познавательно видеть живые пузомерки, чтобы оценить масштаб бедствия на практике. ведь наверняка, для Java и PHP последствия могут быть сильно разными.

                                                        ps: вот что-то меня гложат сильные сомнения, что «быстрые процессоры и хорошие компиляторы» интерпретируемых языков будут рады такому рефакторингу. накидал для JS jsperf.com/replace-temp-with-query — как и предполагалось, результат стал медленнее на половину ;-/
                                                        • 0
                                                          > как и предполагалось, результат стал медленнее на половину ;-/

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

                                                          Но я не думаю, что написание пузомерок — это типовой кейс. Я даже больше скажу, для написания пузомерок лучше JS вообще не брать — рискуете больше, чем в 2 раза проиграть.
                                                        • 0
                                                          Было бы неплохо обновления через rss получать.
                                                          • 0
                                                            спасибо, почитал, затянуло аж до утра)
                                                            • 0
                                                              1. Берем книгу Мартина Фаулера — Рефакторинг
                                                              2. Создаем перелинкованный ресурс по книге, аля wiki
                                                              3. ???
                                                              4. PROFIT!

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

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