BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Standardy kodowania dla C#

31-07-2005 01:28 | blc
Zalety stosowania i przykłady standardów kodowania dla C#.

1. Wstęp

Standardy kodowania są bardzo ważne przy tworzeniu oprogramowania. Określają ogólny format dla kodu źródłowego i komentarzy. Ułatwiają programistom współużytkowanie kodu, wyrażanie swoich pomysłów w sposób czytelny dla całego, być może zmieniającego się w czasie, zespołu pracującego nad danym projektem. Jeżeli każdy członek zespołu będzie stosował ten sam standard, powstały kod źródłowy będzie łatwiejszy w czytaniu, zarządzaniu i poprawianiu, ponieważ będzie napisany spójnym stylem. Czytelny kod źródłowy zmniejsza ryzyko wystąpienia błędu.

W dalszej części artykułu przedstawię najważniejsze, moim zdaniem, punkty, które powinny znaleźć się w każdym standardzie kodowania, jak również przedstawię zalecenia dla C#.

 

2. Format

Format obejmuje użycie białych znaków, wcięć, maksymalną długość linii kodu itp. Pewne standardy mogą obejmować zalecane ustawienia edytora (np. tabulatory). Dla C# zaleca się np. by pliki miały nie więcej niż 500 (plus kod wygenerowany automatycznie), a metody nie więcej niż 25 linii kodu. Długość linii nie powinna przekraczać 80 znaków, a wcięcia powinny mieć 3 albo 4 znaki. Każdy nawias "{" oraz "}" powinien się znaleźć w nowej linii.

 

Przykład:

Źle:

[Kod C#]

111:     while (index >= 0)

112:     {

113:         if (book[index].IsAvailable == true) {

114:              bookAvailableCounter++;

115:         }

116:         else

117:            bookNotAvailableCounter++;

118:      index++;     

119:     }

 

Uwagi:

Linia nr 113: Unikamy porównywania zmiennych logicznych do wartości true czy false. Nawias "{" powinien znaleźć się w nowej linii

Linia nr 114: Wcięcie ma długość 5, powinno być tak jak w linii 113. - 4 spacje

Linia nr 117: Instrukcja dla else powinna być ujęta w nawiasy {}, tym bardziej, że instukcja dla if jest w nawiasach.

Wcięcie powinno mieć długość 4 - jest 3.

Linia nr 118: Wcięcie długości 1, powinno mieć długość 4

 

Po dostosowaniu się do powyższych uwag, poprawnie sformatowany kod wygląda jak poniżej:

 

Dobrze:

[Kod C#]

         while (index >= 0)

         {

             if (book[index].IsAvailable)

             {

                 bookAvailableCounter++

             }

             else

             {

                 bookNotAvailableCounter++;

             }

             index++;     

         }

 

 

3. Struktura kodu

Nazwy projektów, przestrzeni nazw, plików źródłowych, klas, struktur i wyliczeń powinny być w formacie PascalCase (każde podsłowo nazwy zaczynamy od dużej litery). Mimo, że odradza się stosowanie notacji węgierskiej, zaleca się by nazwy interfejsów poprzedzać dużą literą „I”.

W jednym pliku źródłowym powinna znaleźć się definicja tylko jednej klasy czy wyliczenia.

Definicję klasy należy umieścić w pliku o tej samej nazwie.

 

Przykład:

Źle:

Plik My_Interfaces.cs

 

[Kod C#]

001:     using System;

002:     namespace MyProject

003:     {

004:         public interface Shape

005:         {

                 //…

             }

           

101:         public interface Idrawer

102:         {

...              //…

             }

         }

Koniec pliku My_Interfaces.cs

 

Uwagi:

Linia nr 004: Nazwy interfejsów poprzedzamy literą „I”.

Linia nr 101: Nazwy interfejsów zapisujemy w formacie PascalCase.

W pliku powinna znaleźć się definicja tylko jednego interfejsu. Nazwa pliku powinna być taka jak nazwa interfejsu.

 

Poprawny kod wygląda następująco:

 

Dobrze:

Plik IShape.cs

[Kod C#]

001:     using System;

002:     namespace MyProject

003:     {

004:         public interface IShape

005:         {

                 //…

             }

         }

Koniec pliku IShape.cs

 

Dla drugiego interfejsu osobny plik:

 

Plik IDrawer.cs

[Kod C#]

001:     using System;

002:     namespace MyProject

003:     {

004:         public interface IDrawer

005:         {

                 //…

             }

         }

Koniec pliku IDrawer.cs

 

 

3. Nazewnictwo

Nazewnictwo określa jak programiści powinni nazywać swoje metody, klasy, zmienne, zdarzenia, parametry funkcji itp.

Odpowiednie nazwy metod i zmiennych są kluczem do zrozumienia logicznego przepływu

aplikacji. Stosujemy tylko anglojęzyczne nazwy. Zazwyczaj zapisujemy je w formacie PascalCase lub camelCase (od PascalCase różni się jedynie tym, że pierwszy znak pierwszego słowa nazwy piszemy z małej litery).

 

Metody:

Nazwa metody powinna opisywać CO dana metoda robi, a nie JAK to robi. Powinny one zachowywać pewien poziom abstrakcji - np. GetNextStudent() mówi o wiele więcej

niż GetNextArrayElement(). Nazwy metod powinny być w formacie PascalCase, zaczynać się od czasownika (oznaczającego akcję np. Get, Analyze, Show, Calculate) poprzedzającego rzeczownik (oznaczający na czym jest wykonywana akcja). Metody zwracające obiekty powinny mieć nazwy opisujące zwracaną wartość np. GetObjectState().

Przeładowane metody, powinny wykonywać podobne zadania.

Parametry funkcji zapisujemy w formacie camelCase, ilość parametrów nie powinna przekraczać 7.

 

Zmienne:

Pola o dostępie public i protected powinny być w formacie PascalCase. Pola o dostępie private piszemy w formacie camelCase z przedrostkiem "m_" (od member). Właściwości nigdy nie poprzedzamy prefiksem typu "Get" czy "Set".

Zmienne lokalne piszemy w formacie camelCase.

Nie stosujemy jednoliterowych nazw zmiennych (z wyjątkiem pętli for). Zamiast "i" piszemy np. "index".

Jeżeli używamy skrótów, powinny być one powszechnie znane i sukcesywnie przez nas stosowane. Jeżeli np. dla "amount" decydujemy się używać skrótu "amt", to w kodzie nie powinna pojawić się zmienna czy metoda, w której nazwie pojawi się pełne słowo "amount" czy tez inny skrót, np. "amnt", gdyż wprowadza to niepotrzebne zamieszanie i dezorientuje czytającego kod.

Do zmiennych przechowujących wyliczenia, warto dodać sufiks typu: Average, Sum, Count, Max, Min.

Zmiennym logicznym warto dodać prefiks typu: Can, Has, Is.

Pola klas nie powinny mieć przedrostka w postaci nazwy klasy np. pole o nazwie "BookTitle" w klasie "Book" jest już redundancją (powinno być samo "Title").

 

Przykład:

Źle:

[Kod C#]

101:     Student student = GetNextArrayElement();

102:     bool Good = Analyze_this(student.GetSurname, student.StudentName,     student.GetClassID, student.GetYear, getStudentNotes(student.ID), studentCounterAmt, factor, DateTime.Now);

103:     if (good)

104:     {

105:         goodStudentsAmount++;

106:     }

 

Uwagi:

Linia nr 101: Nazwa funkcji nie powinna zdradzać szczegółów implementacji, powinna być bardziej abstrakcyjna.

Linia nr 102: Nazwa funkcji powinna być w formacie PascalCase, „Analyze_this” jest niejednoznaczne, może prowadzić do nieporozumień, utrudnia zrozumienie kodu. Nazwa tej funkcji powinna „mówić”, że zwraca odpowiedź na pytanie, czy analizowana osoba jest dobrym studentem.

                        Dodatkowym utrudnieniem zrozumienia kodu jest liczba argumentów – aż 8, w takiej sytuacji należy przekazać je w klasie, lub przemyśleć konstrukcję.

Przeglądając parametry możemy zauważyć, że właściwości w klasie Student mają nazwy zaczynające się od „Get” – co również jest powszechnie odradzane.

Drugi parametr wywołania funkcji to właściwość StudentName z klasy Student. Przedrostek tej nazwy to redundancja.

Zmiennej logicznej warto dodać przedrostek „is”, oraz ponieważ jest to zmienna lokalna powinna być w formacie camelCase (jest PascalCase).

Czwarty od końca parametr to wywołanie funkcji getStudentNotes(...) – nazwy funkcji powinny być w formacie PascalCase.

Linia nr 105: Przyglądając się trzeciemu od końca argumentowi wywołania funkcji w linii 102 możemy zauważyć, że dla „amount” zastosowano tam skrót „amt”, tymczasem w rozważanej tutaj linii mamy zmienną o nazwie „goodStudentsAmount” – czyli zrezygnowano ze stosowania skrótu dla „amount”. Jak wspomniałem wcześniej, używanie na przemian skrótów i ich pełnych nazw jest odradzaną praktyką.

 

Poprawny kod, po zmianie definicji klas i metod mógłby wyglądać następująco:

 

Dobrze:

[Kod C#]

101:     Student student = GetNextStudent();

102:     bool isGoodStudent = GetStudentQuality(student,

103:                                            studentCounterAmt,

104:                                            factor,

105:                                            DateTime.Now);

106:

107:     if (isGoodStudent)

108:     {

109:         goodStudentsAmt++;

110:     }

  

 

4. Komentarze

Zaleca się pisanie komentarzy w języku angielskim. Należy jednak unikać przesady - nie należy komentować oczywistych instrukcji - pamiętajmy, ze dobrze napisany, czytelny kod, nie potrzebuje komentarzy. Każda metoda czy pole klasy o dostępie public powinna być poprzedzona

komentarzami ///<summary>. Należy bezwzględnie unikać komentarzy w formacie /* ... */ i stosować jedynie komentarze //.

 

Przykład:

Źle:

[Kod C#]

/* Returns Student at ‘id’ element

 * in students array.

 */

public Student GetStudent(int id)

{

    //…

}

 

Uwagi:

Nie stosujemy komentarzy /* … */.

Przed definicją funkcji o dostępie public powinny się znaleźć komentarze <sumary>.

 

Poprawne komentarze:

Dobrze:

[Kod C#]

///<summary>

///Get Student with given student identifier

///</summary>

///<param name=”studentId”>student identifier</param>

///<returns>Student with given identifier or null if such student not exists

///</returns>

public Student GetStudent(int studentId)

{

    //…

}

 

 

5. Podsumowanie

Na podstawie przedstawionego powyżej zarysu standardu kodowania, łatwo sobie wyobrazić, że stosowanie standardu może bardzo ułatwić życie programistom. Intuicyjne nazwy metod czy pól pozwalają, czytając kod, oderwać się od szczegółów implementacji i przejść na pewien poziom abstrakcji, dzięki czemu łatwiej jest zrozumieć sposób działania programu, poprawiać kod, rozbudowywać i zarządzać nim. Trzymanie się ustalonych konwencji jest szczególnie ważne w programowaniu ekstremalnym (ang. Extreme Programming), gdzie z założenia para programistów pisze kod bez szczegółowego planu, dopisując kolejne funkcjonalności. Niespójny styl pisania może prowadzić do niejednoznaczności, wprowadzić niepotrzebne zamieszanie i w efekcie zaowocować kompilującą się sieczką niezrozumiałych instrukcji, przywołującą na myśl żart o tym jak to informatyk robił huśtawkę na drzewie dla swojej córki...

 

Osobom zainteresowanym pełnymi standardami dla C# polecam następujące pozycje:

- http://home.comcast.net/~lancehunt/CSharp_Coding_Standards.pdf - autor: Lance Hunt.

- http://www.idesign.net/idesign/download/Idesign Csharp Coding Standard.zip – autor: Juval Lowy, tutaj znajdziemy także zalecenia dotyczące konfiguracji środowiska programistycznego.

tagi: C#

Komentarze 3

el_suchy
el_suchy
4 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Może się i czepiam, ale "nadmiar" to takie ładne polskie słowo, a "zbędny dodadek" to taka obrazowa fraza, natomiast "redundancja" pachnie wykładowcami, którzy swojemu stanowisku dodają powagi różnymi takimi wyrazami z zakurzonych książek...
Jakub Gutkowski Redaktor
Jakub Gutkowski
1270 pkt.
Senior
MVP
21-01-2010
oceń pozytywnie 0

Zamiast czytac artykul polecam:

http://blogs.msdn.com/kcwalina/default.aspx

jak i wiele innych ciekawszych miejsc w sieci na temat pisania kodu w C#.

Do takich zrodel internetowych naleza nawet strony msdn'a:

http://msdn.microsoft.com/netframework/programming/classlibraries/

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconnetframeworkdesignguidelines.asp

 

Warto tez wspomniec, iz FxCop jak i inne aplikacje do STAT wspieraja programistow w pisaniu kodu - warto wiec sie z nimi takze zapoznac.

User 115079
User 115079
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Przyjemny artukuł porządkujący sprawę pisania kodu. Każdemu programiście piszącemu kod w zespole przyda się takie określenie zasad. Myślę też, że młodzi programiści, którzy dotychczas pisali sami, bardziej po studencku niż w procesie produkcyjnym, powinni rozpocząć od tej publikacji zanim zasiądą do kodowania.
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.