Często słyszy się, że programiści powinni pisać kod, który nie będzie silnie zależeć od pozostałych elementów. Dobrze jakby był oparty na interfejsach, a klasy oraz metody nie były zbyt duże aby dało się go łatwo ogarnąć i zrozumieć. W ogóle – ma być cud-miód.
Pytanie tylko jak tego dokonać nie zaprzęgając zbyt wielkich zasobów ludzkich do sprawdzania tego wszystkiego “ręcznie”? Z pomocą tu przychodzi NDepend – narzędzie do statycznej analizy kodu. Zobaczmy, jak więc może ono nas wspomóc w codziennej, ciężkiej pracy programisty.
Instalacja narzędzie jest bajecznie prosta bo jej nie ma (najprostsze rozwiązania są najlepsze :]) – wystarczy tylko rozpakować i już możemy działać.
Strona główna narzędzia |
Strona główna
Strona główna przypomina trochę tę znaną z VS. Daje nam dostęp do najbardziej potrzebnych funkcji i sugeruje, co możemy zrobić.
Mamy więc listę ostatnio badanych projektów, możemy także rozpocząć analizę solucji bądź też pojedynczych projektów. Ciekawa jest też opcja porównania 2 wersji tego samego kodu. Więcej o tym później.
Jako dodatek mamy też możliwość zainstalowania NDepend’a jako dodatku do VS oraz do Reflectora. Tego ostatniego nie używam (przerzuciłem się na inne rozwiązania) a dodanie NDpened’a jako AddIn’a do Visual Studio da nam dostęp do wszystkich funkcji narzędzia bez wychodzenia z naszego ulubionego edytora. Help zawarty w sekcji ‘Getting Started’ pozwoli nam zapoznać się z możliwościami i rozpocząć pracę z narzędziem pełną parą. Tyle jeśli chodzi o ekran startowy. Zobaczmy, co mamy dalej.
Po wybraniu ‘VS solutions and VS projects’ NDepend jest na tyle miłe, że listuje nam projekty, nad którymi ostatnio pracowaliśmy, więc nie musimy ich szukać. Nice. Dodatkowo daje nam możliwość filtrowania po tym, w której wersji VS był tworzony projekt – od 2005 (ktoś jeszcze pamięta?) do najnowszego 2012. Sweet 🙂
Jako, że ostatnio pracuję nad kodem dotnetomaniaka (wprowadzając to mniejsze to większe zmiany) postanowiłem zbadać kod KiGG’a, na którym jest on oparty.
Po analizie projektu otwiera się strona raportu. Strona, bo NDepend zwraca nam raport z analizy w postaci strony HTML.
Strona raportu |
Raport od razu podaje nam najbardziej kluczowe informacje. Metryki aplikacji – liczbę linii kodu, assemblies, przestrzeni nazw itp.
Raportuje także o regułach, które nasz kod łamie i które powinniśmy w jakiś sposób usunąć.
Fajnie, że przy każdej złamanej regule widzimy zapytanie (o nich będzie później), którego wykonanie poskutkowało wypluciem tych a nie innych obiektów niespełniających norm.
Lista problematycznych klas |
Kilka dużych klas, którym dobrze by było się przyjrzeć. Podobnie w przypadku pozostałych reguł, którym NDepend poddaje nasz kod. Nawet nie wiem ile ich jest, ale przeglądając grupy reguł jest tego sporo. Jeśli jednak czegoś by nam brakowało, spokojnie możemy sobie to dopisać, bo NDepend dostarcza język CQLinq, podobny do LINQ język zapytań do tworzenia reguł. Niektóre reguły są (dla mnie) dziwne – np. poprzedzanie pól statycznych przedrostkiem s_ a po komentarzu w regule (// This naming convention provokes debate. Don’t hesitate to customize the regex of NameLike to your preference.) widać, że nie tylko dla mnie. Na szczęście można je dla danego projektu wyłączyć, zmienić czy też usunąć.
Reguły są dość ciekawie pomyślane, np. jeśli w twojej wersja UI NDepend wykryje odwołania do kodu z nhibernate’a zaraportuje ci, że tak być raczej nie powinno i fragment ten powinno się zmienić. Dzięki temu uczy dobrych praktyk pisania. Inne reguły trzeba troszkę tuningować np. reguła ‘Declare types in namespaces’ jest przydatna, ale trzeba ją zmodyfikować o warunek, aby nie brała pod uwagę typów anonimowych, bo inaczej trochę opcji zaraportuje. Szybka edycja reguły i odpisanie warunku && n.ChildTypes.Any(x=>x.IsGeneratedByCompiler == false) załatwia sprawę.
Czego mi brakowało tutaj (albo ja tego nie znalazłem) to możliwość odpalenia danej reguły z poziomu edytora Queries and Rules Edit. Mój flow pracy był taki, że poprawiłem kod, który daną regułę łamał i chciałem zobaczyć, jaki wpływ mają moje zmiany na nią. Zamiast uruchomić tylko tę jedną trzeba było odpalić cały zestaw. Reguły działają szybko, więc nie był to problem jednakże przydałaby się opcja uruchamiająca tylko jedną. Na szczęście skrót ALT-F5 ratuje po części sytuację i umożliwia uruchomienie sprawdzania reguł.
Jak już napatrzymy się na złamane reguły – możemy zerknąć na bardziej obrazową formę mówiącą, co nieco o naszym kodzie a mianowicie diagramy.
Do wyboru mamy kilka: graf zależności, macierz zależności, metryka wielkości oraz abstrakcja vs. instancyjność (?).
Dwa pierwsze to po prostu różne sposób na zobrazowanie co od czego zależy w naszym kodzie. Graf albo macierz do wyboru, do koloru. Co kto lubi 🙂
W KiGGu, jak widać, jest całkiem pokaźne drzewo zależności.
CQLinq
CQLinq ma swój własny edytor, który może nie działa jakoś wyjątkowo szybko (pracując z nim widać zauważalne opóźnienia), ale spełnia swoją funkcję a dodatkowo daje nam podpowiedzi, co do pisanej reguły, więc nie trzeba ciągle sięgać do dokumentacji. Zapytania mogę bazować na kilku dostępnych kolekcjach danych (tzw. Domenach), które są wystawione przez NDependa. Dla przykładu, jeśli chcemy operować na typach w naszych assemblies wystarczy, że użyjemy JustMyCode, jeśli potrzebujemy dostać się do dll’ek, od których zależy nasz projekt wybieramy – ThirdParty. Jest jeszcze kilka innych, tak więc nie powinno być problemu ze stworzeniem odpowiedniego zapytania. Dodatkowo, jeśli zależy nam, aby dana reguła nie była łamana, możemy oznaczyć ją jako krytyczną. Przy wykryciu złamania takiej reguły NDepend (a dokładniej apka konsolowa) zakończy pracę ze statusem -1, który to zostanie wychwycony przez nasz system CI i odpowiedni raport zostanie wysłany do odpowiednich osób (tę część z wysyłaniem maili musimy zakodować sobie sami – nDepend jest świetny, ale tego nie robi :]).
Okno edytora reguł |
Analiza różnicowa
Ciekawą opcją jest możliwość analizy różnicowej. NDepend daje nam możliwość ustalenia wersji bazowej a następnie wyświetlania tylko zmian, które nastąpiły od tejże ustalonej wersji. Dzięki temu NDepend może posłużyć nam za narzędzie trzymające informacje o zmianach w naszym kodzie. Opcja jest o tyle ciekawa, że możemy wyszukać nie tylko zmieniony kod, ale np. tylko kod, który został dodany. Mało imponujące? Co powiecie na możliwość wykrycia zmienionych komentarzy? Czy kodu, który stał się bezużyteczny po zmianach w innych obszarach?
Oczywiście nie namawiam do rezygnacji z repozytorium. git czy svn zawsze się przyda, ale jest to miły dodatek, bo w przypadku wykrycia jakichś zmian możemy je zanalizować bez potrzeby opuszczania IDE.
Build Task
Gdyby za każdym razem po zmianie naszego kodu trzeba było uruchamiać narzędzie i analizować zmiany, to choć NDepend wspiera taki case wyśmienicie za pomocą wspomnianej wyżej analiza, jest lepsza metoda. Można uruchomić NDepend’a jako taska już po buildzie i zintegrować wyniki z wynikami innych testów, które robimy na naszym kodzie po checkin’ie. Szczególnie prosta jest integracja ze świetnym TeamCity, którego używam w swoich projektach. Opisywać całego procesu nie muszę bo jest on podany na stronach NDepend’a – Build Process / Continous Integration / Reporting. 10 minut później mam już wyniki z analizy na zakładce w TeamCity – jedyny minus, że z jakiegoś powodu nDepend potrzebuje ścieżek absolutnych do plików projektu. Oczywiście na sztywno zapisywać ich w pliku msbuilda nie ma sensu, ale i na to jest sposób.
Power Tools
Power Tools to taka mała przydatna aplikacyjna o możliwościach zestawu wytrychów :). Jak brakuje ci czegoś w GUI możesz sobie dopisać i sprawdzić w tej konsolowej aplikacji. Dla przykładu jest tam opcja ‘.NET Framework v3.5 and v4.X installed, Core Public API Changes’, które po chwili działania podaje nam jak na dłoni zmiany w publicznym API pomiędzy tymi dwoma wersjami .NETa. Dzięki niemu dowiemy się, że 18 publicznych typów dostępnych w 3.5 zostało usuniętych w 4.0.
Narzędzie robi ciężką robotę a więc i nie jest bez błędów. Udało mi się je wysypać 🙂
Jakbym miał porównać to Power Tools to taki R2D2. Mały, ale jak czegoś potrzeba to on na pewno to ma lub wie jak to wykonać 🙂 Bardzo fajne narzędzie dla geeka.
By ~DaSK~ |
Jak na chwilę obecną oceniam nDependa jako przyjaciela w codziennej pracy programisty. Można dzięki niemu wykryć miejsce, którym warto się przyjrzeć, aby kod był lepszy. Sądzę, że posty o nim jeszcze się pojawią, jako że możliwości narzędzia są ogromne.
Founder of Octal Solutions a .NET software house.
Passionate dev, blogger, occasionally speaker, one of the leaders of Wroc.NET user group. Microsoft MVP. Podcaster – Ostrapila.pl