Okazjonalne (regularne) czyszczenie kodu Resharperem

Powiedzmy, że mamy projekt, w którym wcześniej nie znano Resharpera. Otwierając taki kod „wszystko świeci” na różne kolory sugerując, że mamy w kodzie wiele problemów. Moje doświadczenie programistyczne mówi mi, że warto wysprzątać te miejsca, ponieważ na wstępnie z automatu poprawi się nam wiele bugów i znacznie zwiększy czytelność.

cleanup code in resharper

I tutaj staje się przed problemem czy poprawiać wszystko? Czy tylko ważne rzeczy? Czy też przy okazji te automatyczne poprzez Alt+Enter?

Kiedyś przerobiłem cały kod w solucji za pomocą opcji „Cleanup Code” (PPM na projekcie/solucji/katalogu).

cleanup code in resharper

Na początku żeby zacząć utworzyłem nowy profil, nazwałem go „just remove unused references”, i jak widać na obrazku robi to oraz dodatkowo sortuje. Jest to „bezpieczny” niewymagający naszej ingerencji refactoring. Dzięki niemu gdy będziemy już z głową refaktorować kod (usuwać duplikacje, zmieniać strukture itp, itd) nie będziemy się rozpraszać rzeczami, które może poprawić za nas automat.

Warto też od czasu do czasu jeszcze raz przerobić tym automatem cały kod w solution, ponieważ takie rzeczy (jeśli inne osoby o to nie dbają) regularnie zaśmiecają projekty.

Muszę kiedyś napisać o podejściu „Resharper green”, może to rzuci trochę więcej światła.

Jak nie dać się zwariować napływowi informacji

Angielski tytuł brzmiałby „It’s not what you read, it’s what you ignore” bo jest on tytułem znakomitego wystąpienia Scotta Hanselmana:

Od siebie mogę dodać kilka rzeczy, które robię:

  • Email prywatny w pracy jest w nieużywanej przeglądarce, więc prawdopodobieństwo jego przypadkowego przeglądania jest bardzo niskie.
  • Wyłączenie powiadomień mailowych na komórce (zarówno głosowych jak i wizualnych).
  • W pracy na stałe włączony jest tylko Slack projektowy.
  • Wyłączenie powiadomień Slackowych na komórce (tylko głosowe, wizualne zostały).

Dwa powyższe punkty (o emailach) sprawiły, że na dzień dzisiejszy mam +1000 nieodebranych emaili… i bardzo dobrze mi z tym 🙂 Oznacza to, że pewnie te rzeczy nie były tak ważne. Zysk z tego taki, że nic mnie w ciągu dnia nie pinguje i nie odrywa z tego co akurat robię – BEZCENNY. Z drugiej strony kiedyś już w 90% napisałem posta o Inbox Zero, bo to też jest fajne i chciałbym do tego wrócić. Na obecna chwilę nie chcę jednak zaprzątać sobie głowy zadaniem sprzątania skrzynki. Najważniejsze rzeczy mają odpowiednie priorytety i się dzieją.

Do przemyślenia w najbliższym czasie jest czy nie zrobić sobie kilku godzin w ciągu dnia z wyłączonym Outlookiem. Już tak kiedyś pracowałem – czasem trzeba wrócić z powrotem do dobrych, ale zapomnianych praktyk.

A jakie są wasze productivity tips?

Code Review a spacje i inne pierdoły

Chodzi o taką sprawę:

couple random spaces in Code Review

Te ciemno zielone to kilka dodatkowych spacji, które się pojawiło (a nie było ich wcześniej). Inne to: dodatkowo zbędna, podwójna linia, brak pustej linii, brak spacji w parametrach lub zbyt duża ich liczba, itp, itd.

Przypadkowo podczas pracy nad kodem gdzieś się pojawiło kilka spacji za dużo lub za mało. Czy chcielibyśmy przypieprzać się do takich rzeczy na Code Review? – nie bardzo, są ciekawsze rzeczy do kminienia. Jak unikać takich przeszkadzajek:

  • Formatować kod przed commitem, a najlepiej na bieżąco, skrót Ctrl+K, Ctrl+D.
  • Jeśli powyższego nie możemy zrobić, bo ogólnie cały kod jest syfiasty gdy chodzi o wcięcia/formatowanie to możemy formatować tylko kod, który dodaliśmy. Zaznaczamy kod i skrót Ctrl+K, Ctrl+F. To akurat robię rzadko.
  • Jeśli już nie możemy (albo nie chcemy) korzystać z automatycznego formatowania to przed pushowaniem do centralnego repozytorium powinniśmy oczyścić commity z takich przeszkadzajem (git rebase interactive).
  • Już naprawdę w ostateczności gdy nic z powyższych nie podziałało to podczas tworzenia pull requesta (obszerny opis o co w tym biega na przykładzie Git/BitBucketa) zobaczmy wszystkie nasze zmiany. Na tym etapie wyłapiemy te pierdoły, na które będzie tracił czas każdy robiący Code Review (a czasem jest to kilka osób, których czas byśmy zmarnowali).

Innym podejściem jest włączeniem do projektu StyleCopa. Dzięki temu wymusimy pewne standardy formatowania, czyli brudną robotę odwali za nas narzędzie.

Uciekaj szybko z metody i usuwaj „else”

Chciałem w sumie tylko podlinkować:

What really grind my gears #1 – IIIIIIIIIIIIIIIIF! by Oskar Dudycz.

TL;DR, taki kod:

zamieniamy na:

Codzienna prasówka – The Morning Brew

Chciałbym dziś napisać o jednej z metod poszerzania wiedzy.

Od zawsze nazywało się to dla mnie The Morning Brew. Jak sam autor pisze:

The Morning Brew
is a daily .NET software development link blog published by Chris Alcock a software developer from the north west of England.

Chris ma w tym doświadczenie, to już #2468 odcinek, pierwszy był 10 lat temu!

the-morning-brew-logo

Zawartość

Można się spodziewać kilkunastu lub dwudziestukilku linków do artykułów, które warto przeczytać a pojawiły się poprzedniego dnia (lub od ostatniej publikacji The Morning Brew, nowe wpisy ukazują się tylko w dni pracujące). Wybierane są tak zwane perełki. Dzięki temu nie zaglądam już do innych zagranicznych agregatorów technologicznych.

Czego tam szukam?

Nie warto czytać wszystkiego, przebiegam po tytułach i opisach. Już po sekundzie wiem co mnie interesuje. Dziennie klikam kilka linków. Więcej nie warto bo tematy są tam bardzo szerokie. Mają wspólny mianownik i jest nim .NET, ale trzeba być realistą, czytam o tych rzeczach, które przydadzą mi się w codziennej pracy.

Inny przykład to wpisy np Ayende. Jego blog sam w sobie w całości powinien być „must read”, jeśli jednak nie mamy aż tyle czasu to The Morning Brew wybierze dla nas te najciekawsze.

Gdy na co dzień pracowałem z Front Endem, czytałem o nowinkach z tego świata (dużo o TypeScript). Teraz pracuję w oderwaniu od UI (silnik obliczeniowy), więc nie klikam w nic związanego z TypeScriptem, a za to poznaję tematy .NET Standard/Core. Gdy projekt się zmieni na FE to znowu TypeScript dostąpi łask. Nie warto czytać na zapas. Samo pobieganie po tytułach daje mi ogólny obraz tego co się dzieje w świecie .NET.

Całkiem przyjemny obowiązek

Uważam, że taka codzienna prasówka, powinna być obowiązkowa dla każdego Architekta/Tech Leada. Przynajmniej jedna osoba w zespole powinna być na bierząco. Takie przejście po tematach bardzo dobrze sprawdza się na komórce/tablecie podczas podróży z pracy/do pracy, podczas posiłku, lub wieczorem gdy nie chcemy odpalać kompa, ale jednak coś by się poczytało.

Polecam każdemu tydzień z The Moring Brew i wyrobienie sobie własnej opinii czy Ci to pomaga oraz wyrobienie własnego sposobu ile i czego czytać.

Prostsze rzucanie wyjątków, gdy nie mamy obsłużonego Enuma

Chcemy rzucić wyjątkiem, gdy mamy przypadek nieobsłużony poprzez case’y. Na przykład gdy pojawiła się nowa wartość enuma Shape.

public string GetDescription(Shape shape)
{
    switch (shape)
    {
        case Shape.Round:
            return "Round";
        case Shape.Square:
            return "Square";
        default:
            throw EnumGuard.CreateMissingEnumException(nameof(shape), shape);
    }
}

Zalety

  • dużo informacji do wyszukania w logach:
    • dostajemy nazwę parametru, który sprawił problem
    • dostajemy Typ, który wyszedł poza zakres
    • dostajemy wartość, która wyszła poza zakres
      (gdy jedyne co mamy to Exception z loga, bug się trudno reprodukuje, to każda dodatkowa informacja jest na wagę złota)
  • łatwa weryfikacja podczas CodeReview: ten oneliner jest zawsze taki sam, zmienia się tylko argument powtórzony w argument i nameof(argument).
  • w definicji nie ma żadnego ręcznie pisanego stringa

Alternatywy pisania „każdy po swojemu”

    throw new ArgumentException("Unhandled type", nameof(arguments.SomethingStrategy));
    throw new NotSupportedException($"Following configuration is not supported: {configuration}");

gdy poniższy kod zostanie przekopiowany to raz na jakiś czas ktoś zapomni że trzeba zmienić stringa, bo już inny typ sprawdzamy

    throw new InvalidOperationException($"Unknown something solution method: '{input.SomethingSolution}'");

czyli za każdym razem trochę inaczej.

Problem i rozwiązanie do rozważenia

Ktoś może zapomnieć wpisać throw i kod

EnumGuard.CreateMissingEnumException(nameof(shape), shape);

się skompiluje. Dlatego metoda ma atrybut [Pure], więc tylko jej wywołanie (brak throw) zwraca uwagę ReSharpera.

Periodic Solution Cleanup

Staram się automatyzować wiele rzeczy. Build skrypt przechodzący lokalnie i na serverze po każdym commit’ie to podstawa. Można to w prosty sposób zrobić. Jest jednak część rzeczy, które są zbyt trudne do automatyzacji, albo po prostu nie da się ich zautomatyzować.

daily cleanup

Wymyśliłem więc, że potrzebuję listę rzeczy, które trzeba co jakiś czas wykonać, aby nic nas nie zaskoczyło podczas sesji testowej lub przed „Releasem”. Później wyewoluowało to w przypominajkę w Outlooku z pełną listą kroków do wykonania. Aktualnie przypominajke mamy dla całego teamu co 2 tygodnie.

Co jest w takiej liście:

To keep clean rules like ReSpeller (which cannot be automated or it is too time consuming) we need to maintain some rules semi-automated or manual. So every 2 weeks responsible person will run the following task (can be also found in my calendar):

@all

  • Delete all branches that are not needed anymore (ie. from old PR)

@Krzysztof Morcinek:

  • Remove all unused „usings”, https://dzienwpracy.wordpress.com/2016/08/17/okazjonalne-regularne-czyszczenie-kodu-resharperem/
  • Adjust namespaces
  • Search all “null” in solution and check how to rewrite them
  • Check if there are any TODOs without owner
  • Update all Nugets (the reason for this is to not spend time on other days to update libraries (and not even think about it)

    ○ Nugets that should not be udpated: SpecFlow

  • Clean build – fresh clone of repo (develop branch) into new folder, run build (not needed every time)
  • Check if on newest ‚develop’ can be run build script on SpecFlow VM

@Dariusz Wenderlich:

  • Verify if no misspelled words are in solution (ReSpeller)

Taka sama lista jest w OneNote (trzeba ją synchronizować).

We wcześniejszym projekcie miałem też punkt o tym, żeby puścić „test integracyjny”. Taki test nie był do końca wyizolowany. Trzeba było dopilnować kilku rzeczy, odpalić UI i rozpocząć automatyczny import trwający kilka godzin, a w tym czasie było się zblokowanym na uruchamianie aplikacji. Jeśli wydaje Wam się, że to słabe podejście to osobiście uważam, że doprowadzenie do takiego stanu to był już krok do przodu. Błędy znajdowaliśmy szybciej albo była pewność, że ich nie ma.

Po kilku miesiącach krok po kroku przy okazji innych tasków udało się ten „test integracyjny” w całości wyizolować i był już regularnie wykonywany na serwerze CI. Opuścił listę Periodic Solution Cleanup.

To tylko jeden z wielu przykładów, ponieważ ta lista jest dobrym miejscem na szukanie czasochłonnych aktywności, które można w całości zautomatyzować.