Jest to jedno z najlepszych narzędzi z jakimi przyszło mi ostatnio pracować

Zacząłem od cytatu, mojego własnego, który został wypowiedziany pomiędzy kilkoma K, przerywanymi P a końcowym Jupi! Do rzeczy, od pewnego czasu mam przyjemność bawić się aplikacją nDepend. Jeżeli ktoś o niej nie słyszał to z grubsza, służy ona analizie rozwiązań .NET poprzez zastosowanie określonych (modyfikowalnych) metryk zgodnych z najlepszymi praktykami tworzenia bibliotek w .NET.

W Internecie naprawdę jest dużo materiałów opisujących jak korzystać z oprogramowania, co oznaczają określone metryki i jak za pomocą nDepend rozwiązywać konkretne problemy (na przykład podmiany biblioteki zewnętrznej X, którą wykorzystujemy w naszym rozwiązaniu na bibliotekę Y). IMO nie ma sensu opisywać sposobów przeprowadzania analizy w nDepend, dlatego też na końcu zamieszczam listę linków, które każda osoba zainteresowana nDepend powinna przejrzeć/przeczytać.

Skoncentruje się na ogólnym opisie narzędzia (UI, funkcje jakie udostępnia itp.), a dopiero na końcu wytłumaczę dlaczego wypowiedziałem takie słowa jakie padły na początku. Nie będzie to artykuł techniczny, oraz nie przejdę konkretnego procesu analizy, druga część miała być już dokładną analizą Microsoft.SharePoint v. 14, jednak ze względu na datę wersji, która posiadam (październik) a zbliżającą się wersją beta (listopad), stwierdziłem iż to nie ma sensu. Zrobię to może później.

Zrzuty ekranu są różne ze względu na to, że były robione na dwóch różnych komputerach, moim PC i Notebooku. Różnica polega na tym iż na PC wygląda to lepiej, zaś problemy opisuje z poziomu Notebooka, miejcie to na uwadze.

UI

Moje pierwsze wrażenie po otworzeniu narzędzia było: muszę mieć większy monitor. Przesiadłem się więc na swój stacjonarny komputer by sprawdzić jak to wygląda na 24 calowym monitorze. I tak, dalej twierdzę, że aby widzieć wszystko ładnie i wyraźnie potrzebny jest duży monitor :) choć są osoby, które pewnie bez przeszkód na małym (17 cali) będą wstanie z tego narzędzia korzystać, dla mnie jest wtedy trochę za mało miejsca, dodatkowo widok okna głównego:

nDepend_fullscreen

nie zachęcił mnie z miejsca do pracy :) tyle rzeczy, kolorki, tekst, co, gdzie, jak. Zgubiłem się :) Na szczęście pomoc oferuje kilka filmików instruktażowych, po których już zacząłem się zapoznawać z narzędziem.

Warto zwrócić uwagę na to iż narzędzie oferuje dwa tryby menu (tak dwa:)), standardowy (File, Edit etc.) oraz Ribon. To akurat plus, osobiście polubiłem Ribon i z Ribonem w nDepend mi się bardzo dobrze współpracuje :)

Jednakże całościowy wygląd ma kilka problemów (u mnie na notebooku), mianowicie okna tak jakby się nie mieszczą, są trochę ucinane (tak mi się zdaje):

ndepend_windowClose

Także czasami brak jest suwaka, i nie wiesz czy wszystko jest poprawnie czy coś się po prostu popsuło. Ribon przy mniejszych rozdzielczościach traci ikonki, a podpowiadanie w zapytaniach nie wyświetla wszystkiego:

ndepend_combo

nDepend_icons

Dlatego zalecam, duży monitor i pracę na pełnym ekranie! :)

Funkcjonalność

Można śmiało wyróżnić następujące główne (zależne od siebie) funkcjonalności:

  1. Matrycę zależności – pokazuje nam – na trochę skomplikowanym grafie – jak nasze rozwiązanie jest zależne między sobą oraz między bibliotekami, które są przez nas wykorzystywane;

     nDepend_matrix

  2. Graf zależności – to co pokazuje matryca ale na grafie, kto co lubi. Plusem grafu jest to iż pokazuje szczegóły, które na matrycy mogą zostać nie wyświetlone – na przykład nie bezpośrednie tworzenie typu/wywołanie metody. To znaczy, że nasza klasa C, woła klasę B, która tworzy instancję obiektu z klasy A, która zaś leży w zewnętrznej bibliotece;

    nDepend_depgrapth

  3. Metryki – schemat reprezentacji metryk, mnie osobiście nie odpowiada, ale też nie wpadłbym chyba na lepszy pomysł :) Ogólnie im dłużej z nim siedzę tym bardziej mi się podoba. Dodatkowo schemat umożliwia oglądanie go poprzez rożne metryki – na przykład liczba linii kodu w metodzie. Przydatny do overview, ale tak by z niego cały czas korzystać to raczej nie;

    nDepend_metrics

  4. Porównywanie bibliotek – umożliwia porównywanie dwóch wersji danej biblioteki, o tym później;
  5. Pokrycie kodu – poprzez wczytanie raportu pokrycia kodu, na przykład na schemacie metryk możemy sprawdzić, które metody są wykorzystywane w całości, które w ogóle nie są uruchamiane itp. coś co normalnie w kodzie robi nam R#, jednakże z tą różnicą iż możemy zaobserwować, że na przykład nasz typ A ma metodę statyczną, która w ogóle nie jest wołana od nas z kodu a i też nie powinna być dostępna na zewnątrz. Warto od czasu do czasu taką analizę przeprowadzić.

CQL

Ponad powyżej opisanymi funkcjami, widnieje CQL. Język zapytań umożliwiający nam wybieranie elementów per dany warunek/metryka. Dla przykładu, zapytanie:

SELECT METHODS FROM ASSEMBLIES "AutoMapper" WHERE IsPrivate

Zwróci nam wszystkie metody z biblioteki AutoMapper, które są prywatne. Dodatkowo na schemacie metryk, wszystkie metody zwrócone przez zapytanie zostaną zaznaczone na inny kolor.

ndepend_automapper

Raporty

Podoba mi się to, iż zaraz po przeanalizowaniu biblioteki tworzony jest raport z podsumowaniem. Czasami mi to całkowicie wystarcza – nie muszę potem wchodzić do aplikacji, jednakże przy dużych bibliotekach, raport może przestać być widoczny (za dużo informacji na jednej stronie), wtedy już należy bezpośrednio skorzystać z narzędzia. Mały przykład raportu:

Integracja

Dodatkową funkcjonalnością nDepend, jest integracja z takimi produktami jak .NET Reflector, Visual Studio 2005/2008, MSBuild, NAnt, Team City czy CruiseControl.NET.

Jeżeli chodzi o .NET Reflector i VS, to integracja ta polega na dostępnie do kilku metod nDepend, które następnie otwierają aplikację i są wykonywane, a nie na zasadzie, że w VS i w .NET Reflector widać nDepend :)

Zaś integracja z narzędziami do buildowania rozwiązań, polega na integracji raportów (z tego co się zorientowałem).

Kiedy i do czego stosować?

To była moja bolączka, mówiąc szczerze. Narzędzie z miejsca nie daje odpowiedzi, ale to tak jak z whisky, trzeba dojrzeć by zrozumieć. Jak wiemy co chcemy się dowiedzieć na temat naszego kodu, nDepend jest wstanie nam dać odpowiedź. Musimy tylko wiedzieć co. A z tym jest problem, do póki nie przeczyta się informacji na temat jakie informacje zwrotne daje nam aplikacja :) zaś po przeczytaniu znów zastanawiamy się do czego można to wykorzystać, i kółko się zamyka.

Stosowanie go codziennie na bibliotece nie ma sensu, to się powinno robić raz na jakiś czas w trakcie programowania i podczas tworzenia wersji ostatecznej. Wtedy też należy określić nasze metryki, które nas interesują (bo nie wszystkie powinny nas zawsze interesować). Dopiero wtedy można zacząć analizę naszego kodu.

Dzięki informacji zwrotnej możemy następnie wprowadzić zmiany do naszego projektu. Zmiany te mogą być poważne (jeżeli dopiero używamy narzędzia pod koniec projektu), lub małe (usunięcie jednej zależności, zorientowaniu się dlaczego tak się dzieje i czy aby na pewno tak powinno być), przy idealnych projektach, zerowe ;)

Do takich podstawowych czynności w analizie możemy zaliczyć:

  • Sprawdzenie czy nasze rozwiązanie jest łatwe czy trudne w utrzymaniu (mniejsza lub większa abstrakcja naszego kodu);
  • Zorientowanie się czy przypadkiem do rozwiązania nie musimy dodać jakiejś niestandardowej biblioteki (może wydawać się to śmieszne, ale jak siedzicie pół roku nad rozwiązaniem, to można zapomnieć o pewnych referencjach dodanych do projektu, jedynie VB.NET umożliwia czyszczenie ich, C# nie);
  • Przeanalizowanie co musi ulec zmianie by móc podmienić bibliotekę X na Y w naszym rozwiązaniu;
  • Sprawdzenie który z naszych typów zawiera za dużo własności i metod, możemy się wtedy zastanowić czy może mały refactoring by nam nie pomógł :);
  • Itp.

Dodatkowo, za pomocą nDepend możemy przeprowadzić analizę porównawczą naszych dwóch bibliotek – na przykład przypadkowo usunęliśmy publiczną metodę zamiast ustawić jej atrybut obsolete. Przydaje się przy produktach.

To co tygryski lubią najbardziej

To co do tej pory zostało powiedziane to przedstawia jedną stronę nDepend. Druga, spowodowała iż osobiście uważam nDepend jako jedno z najlepszych narzędzi z jakich ostatnio korzystałem. Tak specjalnie to pogrubiłem. Tak jak analiza pod względem metryk można stosować od czasu do czasu na swoich bibliotekach, tak w czasach kiedy coraz więcej ludzi tworzy projekty open source, firmy dość często wypuszczają kolejne wersje swoich bibliotek, problemem jest informacja: co zostało zmienione? co zostało usunięte a co dodane do biblioteki?

Gdyby release notes zawierało pełną informację o zmianach jakie zaszły, lub dokumentacja (która istnieje lub nie istnieje) o nich informowała to pewnie na pytanie dało by się odpowiedzieć. Jednakże tak się nie dzieje. Dostajemy nową bibliotekę, chcemy zacząć z niej korzystać i wykorzystać wszystko to co oferuje nowego, albo dowiedzieć się co będziemy musieli zmienić by nasz koda zaczął z nową biblioteką działać.

Do tej pory stosowałem dwa sposoby:

  1. Dodawałem referencję do nowej biblioteki w VS i sprawdzałem czy kod się kompiluje i przechodzi testy, jak tak to ql, jak nie to zaczyna się mordęga;
  2. Otwierałem bibliotekę w .NET Reflector i przeglądałem ją sprawdzając czy coś się zmieniło w tych typach, które pamiętam jak wyglądały.

Nie zależnie od sposobu to zawsze zajmowało czas… i to bardzo dużo czasu. W szczególności w moim ostatnim przypadku – nowej bibliotece Microsoft.SharePoint.dll. Kto jest wstanie spamiętać nazwy 120 metod klasy SPListItem? A dodatkowo zauważy, że metody brakuje lub doszła nowa?

Dopiero nDepend mi pomógł i to bardzo dzięki swojemu językowi zapytań CQL oraz funkcji porównywania bibliotek. Wystarczy podać dwie biblioteki i już możemy na przykład, odpytać się, jakie metody zostały dodane do SPListItem i są publiczne:

SELECT METHODS FROM TYPES "Microsoft.SharePoint.SPListItem" WHERE WasAdded AND IsPublic

Wynik:

ndepend_spsAdded

Jeżeli chodzi o usunięte metody z SPList to mamy zapytanie:

SELECT METHODS FROM TYPES "Microsoft.SharePoint.SPList" WHERE WasRemoved

I taki o to wynik:

ndepend_spsREmoved

Ja po prostu zakochałem się w tej funkcjonalności. Pomyśleć, że zmarnowałem tyle godzin analizując w .NET Reflector rozwiązania kiedy mogłem zadać kilka prostych zapytań. Wiem jedno, nDepend stał się moim nowym narzędziem do codziennej pracy, a Patrick Smacchia jak się pojawi w Warszawie ma u mnie Piwo :)

Podsumowanie

Problem z nami jest taki, że myślimy jak tu wykorzystać nDepend by pomógł nam w naszym rozwiązaniu, a nie jak nDepend może nam pomóc w naszej codziennej pracy. Kiedy koncentrujemy się na naszych przeważnie jednoosobowych projektach to ciężko będzie znaleźć zastosowanie narzędzia, gdy jednak zmienimy punkt siedzenia/widzenia narzędzie to stanie się on naszym przyjacielem.

Linki

Poniżej obiecane linki. Większość pochodzi z pomocy oraz ze strony głównej aplikacji. Zebrałem je tutaj w jednym miejscu – IMO to po prostu pomaga. Dema/Filmy pokazują jak korzystać z aplikacji do osiągnięcia danego celu, zaś jeżeli chodzi o blogi/opisy to nie koncentrowałem się na wszystkich informacjach z sieci, podałem to co może być ciekawe, oraz dwa najważniejsze źródła (blog twórcy na którym jest masa opisów jak można wykorzystać aplikację i do czego, oraz stronę projektu :)). Ogólnie do tych linków macie większości dostęp ze strony nDepend.

PS.: Tytuł miał brzmiać: Krótka historia… ze względu na to, że nie zmieściłem się na 5 stronach A4, zmieniłem go na Długa, przepraszam :)

5 KOMENTARZE

  1. Hej, wspomniałeś o tym, że narzędzie współpracuje z CC.NET. Czy wykorzystujesz CruiseControl w projektach SharePointowych? Mógłbyś coś więcej o tym napisać – o pracy z CC i konfiguracji w kontekście rozwiązań pod SharePointa?

  2. Hej,

    nie, w pracy uzywamy TFS i firma nie ma licencji nDepend, wiec tez nie moge tego "legalnie" wdrozyc. Nie bawem bedzie nowy rok, nowe budzety, wtedy zagadam w firmie, moze przejdzie. Jak tak :) to potem cos napisze na ten temat.

    Ale ogolnie link z postu do CC.NET powinien Ci wskazac droge co i jak – chyba, ze masz na mysli integracje CC.NET z sharePoint (przynajmniej dashboardu).

    Gutek

Comments are closed.