Dobre zasady pisania dużych aplikacji

Ciekawe artykuły dotyczące C#

Moderator: xxSlayeRxx

Dobre zasady pisania dużych aplikacji

Sponsor

Sponsor
 

Dobre zasady pisania dużych aplikacji

Postprzez RyszardDzegan » Pn sty 25, 2010 11:49 am

Wyobraź sobie taki scenariusz: Przypadkiem lub też celowo odpaliłeś jakąś dużą aplikację. W tym momencie postanawiasz jednak z jakiegoś powodu ją natychmiast zamknąć i zająć się czymś innym. Ale co się dzieje? Na początku poraża Cię w oczy ekran powitalny tej aplikacji, który przy okazji zasłania połowę Twojego pulpitu i inne programy, z których chciałbyś może właśnie skorzystać. Chwilę potem zamula Ci się cały komputer. Próbujesz CTRL+ALT+DEL i próbujesz zabić natrętny proces. Komputer zamula się jeszcze bardziej, przetwarza się i liczy coś tam w tle, okna się wieszają, ikony się nie klikają, a Ty dochodzisz do wniosku, że szybciej będzie zrestartować cały system niż czekać aż ta przeklęta aplikacja wreszcie się zamknie.

Chciałbym żebyśmy poruszyli tutaj ten temat. Dlaczego duże aplikacje sprawiają tyle kłopotów? Dlaczego zamulają komputer? Dlaczego nie reagują na polecenia? Ten artykuł przeznaczony jest dla początkujących programistów, którzy chcą dowiedzieć się czegoś o pisaniu większych aplikacji.

Konstruktory.
W praktyce są wykorzystywane do inicjacji pól i zasobów klasy. Problem pojawia się, kiedy klasa jest duża. Wtedy inicjacja wszystkiego, czego potrzebuje zabiera jej trochę czasu. W praktyce często i tak nie używamy znacznej części funkcjonalności klasy. Po co więc ładować tonę zasobów, a potem tą tonę usuwać, skoro większość z tego w ogóle nie będzie użyta? C# posiada metody, a przede wszystkim właściwości. Postarajmy się inicjować zasoby dopiero wtedy, kiedy staną się potrzebne, a nie w momencie powstania instancji klasy. Niech konstruktory będą minimalne. Jeśli mimo tych zabiegów aplikacja nadal wolno się ładuje, spróbujmy wrzucić część inicjacji do oddzielnego wątku, a gdyby użytkownik przypadkiem zażądał dostępu do niezainicjowanej zmiennej poprośmy go aby chwilę poczekał. Na pewno zareaguje na to lepiej niż na zamulony system.

Wątki.
Jeśli jakaś metoda może potrwać zauważalnie długo z punktu widzenia użytkownika, należy użyć wątku i przypisać mu tryb pracy niskiego priorytetu i jeśli to możliwe również tryb pracy w tle. Wtedy nasz program będzie mógł wykonywać skomplikowane obliczenia w sposób niezauważalny, a w razie konieczności natychmiast zaprzestanie pracy.

Wydajny kod vs zrozumiały kod.
To, co najbardziej przyczynia się do powolności aplikacji, bardzo rzadko wynika z powolnych rozwiązań w kodzie. Tak naprawdę nie ma nic gorszego od napisania stu skomplikowanych linii kodu zamiast dziesięciu prostych, żeby przyspieszyć działanie aplikacji o ułamek sekundy. Problem polega na tym, że kiedy do naszego kodu zasiądzie inny programista aby coś zmienić (a przy dużych aplikacjach to jest prawdopodobne), wtedy będzie tracił czas na próby zrozumienia istoty rozwiązania, co oczywiście negatywnie wpłynie na czas pracy nad projektem. Na domiar złego pojawia się ryzyko, że coś zepsuje, ale nawet jeśli uda mu się niczego nie zepsuć, to bardzo możliwe, że powstawia do kodu jakieś obejścia i swoje rozwiązania, które skutecznie zniwelują Twoje starania o przyspieszenie aplikacji o ułamek sekundy. Ostatecznie powstanie wielki, powolny bajzel. Dlatego pisząc kod w zespole należy pamiętać przede wszystkim o kolegach po fachu, a nie o maszynie. Kod powinien być prosty, zrozumiały i opatrzony dokładnymi komentarzami.

Komentarze.
Mało kto daje komentarze do swojego kodu. Jeśli już jakieś są, to zwykle typu "x = null; // Przypisuję x wartość null" itp. To tylko zaśmieca kod i nikomu do niczego się nie przydaje. C# oferuje komentarze XML, które są równie proste w użyciu co zwykłe komentarze, a pomagają mechanizmowi InteliSense w Visual Studio. Pozostałe komentarze powinny informować nie o tym, co robimy w kodzie, bo to każdy widzi, tylko o tym po co to robimy. Np. "x = null; // Wartość x nie będzie już więcej wykorzystywana.

Zachęcam do wypowiadania się na temat i dodawania swoich uwag.
Ostatnio edytowano Pt sty 29, 2010 8:19 am przez RyszardDzegan, łącznie edytowano 1 raz
Avatar użytkownika
RyszardDzegan
Member
 
Posty: 16
Dołączył(a): So sty 09, 2010 6:00 pm
Lokalizacja: Szczecin

Re: Dobre zasady pisania dużych aplikacji

Postprzez MaRCHeW » Wt sty 26, 2010 7:52 am

Witam.

Dobry tekst. Odnośnie komentarzy i pracy w grupie to dobrym zwyczajem jest używanie StyleCop - http://code.msdn.microsoft.com/sourceanalysis - choć pisząc samemu też warto go używać.

Pozdrawiam
Karol Marchewka
MaRCHeW
Member
 
Posty: 34
Dołączył(a): Śr wrz 12, 2007 6:07 pm

Re: Dobre zasady pisania dużych aplikacji

Postprzez RyszardDzegan » Śr sty 27, 2010 12:57 pm

Metoda ToString(CultureInfo.InvariantCulture)
Dobrym zwyczajem w pracy nad międzynarodowymi projektami jest używanie przeciążonych metod ToString() lub string.Format() z parametrem IFormatProvider. Dlaczego? Rozważmy przykład:
Kod: Zaznacz cały
0.8.ToString();

Jaki będzie wynik tej operacji? Niestety to zależy od ustawień regionalnych. W polskiej kulturze używamy przecinka jako separatora dziesiętnego, natomiast inne kraje używają raczej kropki. Jeśli mamy polskie ustawienia regionalne otrzymamy string "0,8", w przypadku innych będzie to prawdopodobnie "0.8". Widać więc, że ustawienia regionalne dotyczą nie tylko waluty, ale również tak podstawowych danych jak liczby zmiennoprzecinkowe. Teraz wyobraźmy sobie, że mamy jakiś atrybut, który przyjmuje wartość zmiennoprzecinkową x jako string, np.
Kod: Zaznacz cały
Attributes["DoubleValue"] = x.ToString();

W tym momencie narażamy naszą aplikację na widmo zagłady z niewyjaśnionych przyczyn na niektórych systemach, które mają inne niż my ustawienia regionalne. Aby uniknąć tego typu problemów najlepiej zamienić wcześniejsze przypisanie na poniższe:
Kod: Zaznacz cały
Attributes["DoubleValue"] = x.ToString(CultureInfo.InvariantCulture);

Dzięki temu możemy mieć pewność, że niezależnie od ustawień regionalnych otrzymamy ten sam wynik.
Różnice kulturowe mogą nieść ze sobą poważne skutki. Fizycy mogą np. wysłać wyniki w kilometrach, a jakiś głąb przetłumaczy to dla amerykanów w milach i katastrofa murowana. Data 2010/03/05 to dla nas piąty marca, a dla amerykanów trzeci maja.
Ostatnio edytowano Pt sty 29, 2010 8:21 am przez RyszardDzegan, łącznie edytowano 1 raz
Avatar użytkownika
RyszardDzegan
Member
 
Posty: 16
Dołączył(a): So sty 09, 2010 6:00 pm
Lokalizacja: Szczecin

Re: Dobre zasady pisania dużych aplikacji

Postprzez Mikoj » Śr sty 27, 2010 3:33 pm

Przy pracy grupowej najlepiej rozbić projekt na warstwy.
Np warstwa odpowiedzialna za dostarczenie, tworzenie , edycje danych
warstwa odpowiedzialna za wyświetlenie danych
warstwa odpowiedzialna za kontrole danych w projekcje
etc itd.

Wszystko uzależnione jest od wielkości projektów nie od osób bo jak sobie rozbielmy aplikacje na warstwy to lepiej jest nam samemu poruszać się po tych elementach, co idzie w parrze ze ktoś inny też bez problemu "siądzie" na wasz kod.
Polecam zapoznać się z takimi wzorcami projektowymi jak MVC, MVP
Ja osobiście polecam MVP naprawdę sprawdza się.
Będzie Lepiej...
Avatar użytkownika
Mikoj
Member
 
Posty: 220
Dołączył(a): N maja 06, 2007 12:06 pm
Lokalizacja: Kraków

Re: Dobre zasady pisania dużych aplikacji

Postprzez RyszardDzegan » Cz sty 28, 2010 4:36 pm

Wyłapywanie błędów za pomocą klasy Debug
W dużych projektach kliknięcie jednego przycisku może pociągnąć za sobą wywołania dziesiątki metod. Teraz niech coś, gdzieś się po drodze zepsuje. Musimy przeglądać cały stos wywołań aby dowiedzieć się, co poszło nie tak. Takie błędy bywają często bardzo frustrujące. Na szczęście rozwiązanie jest bardzo proste i w zasięgu każdego nowicjusza. Chodzi o klasę System.Diagnostics.Debug. Ta funkcja posiada takie metody jak: Write, WriteLine, WriteIf, WriteLineIf, Print i Assert. Metody te pozwalają wypisać komunikat o potencjalnym błędzie np. do okna Output w VisualStudio albo na konsolę. Dzięki temu, kiedy podczas działania aplikacji wydarzy się coś podejrzanego, od razu będziemy wiedzieli dlaczego i gdzie zanim aplikacji naprawdę stanie się krzywda. Oto przykład: Wyobraźmy sobie, że gdzieś w gąszczu wywołań metod pojawia się taki kod:
Kod: Zaznacz cały
...
Control control = (someObject as Control);
...

Teraz wyobraźmy sobie, że someObject jakimś cudem nie jest typu someControl, choć nie ma do tego prawa w tym miejscu. Zmienna control będzie więc posiadała wartość null. Następnie zostanie ona gdzieś przekazana, a potem dalej i będzie sobie wędrować po aplikacji, aż w końcu dojdzie do miejsca control.DoSomeMethod() i poleci NullException. Przezornie możemy postawić w tym miejscu blok try{}catch{} lub zwrócić false aby zaznaczyć, że w funkcji coś się wysypało i jechać z programem dalej. Choć jest to głupie, to w praktyce duże, komercyjne aplikacje zawierają masę takich przekrętów aby tylko aplikacja nie wywaliła się na oczach klienta. Jednak prędzej, czy później będziemy musieli zmierzyć się z takimi czarami w kodzie i spędzimy bezsenne noce na szukaniu miejsca błędu. Aby uniknąć takich problemów robimy następującą zmianę:
Kod: Zaznacz cały
using System.Diagnostics;
...
Control control = (someObject as Control);
Debug.WriteLineIf(control == null, "Zmienna control nie powinna mieć w tym miejscu wartości null.");
...

Dzięki temu aplikacja może lecieć z błędem dalej, a my zawsze będziemy mieli komunikat o zagrożeniu i w razie potrzeby łatwiej nam będzie zafixować problem.
Avatar użytkownika
RyszardDzegan
Member
 
Posty: 16
Dołączył(a): So sty 09, 2010 6:00 pm
Lokalizacja: Szczecin

Re: Dobre zasady pisania dużych aplikacji

Sponsors

Sponsor
 


Powrót do Artykuły

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość