Standardy kodowania — dobre praktyki programistyczne

03.03.2020 Krzysztof Baraniecki
dobre praktyki kodowania - wskazówki dla programistów

Określenie dobre praktyki zastosować można nie tylko do programowania. W internecie wiele jest oficjalnych i zawiłych definicji tego terminu, ale można go uprościć. Dobre praktyki oznaczają chęć nabrania nawyków i wprowadzenia nowych metod pracy, aby poprawić jej jakość, jednocześnie wykonując ją szybciej. Dobre praktyki skupiają się również na długoterminowej pracy przy projekcie. Należy realizować go w sposób, który nie spowolni lub uniemożliwi później zmian, lub poprawek. Dobre praktyki oznaczają również podnoszenie jakości kapitału ludzkiego, czyli przekazywania wiedzy dalej, aby poziom branży wzrastał.

Czym są dobre praktyki w programowaniu?

W programowaniu dobre praktyki oznaczać mogą czysty kod, czyli taki, który będzie uniwersalnie zrozumiały i prosty w konstrukcji, ale przy tym wszystkim – w pełni funkcjonalny. Celem jest stworzenie kodu na tyle przejrzystego, żeby po powrocie do niego po kilku miesiącach jego funkcje i rozwiązania wciąż były oczywiste. Na tyle przejrzystego, żeby programista zewnętrzny był w stanie go zrozumieć i przy nim pracować. Twórz kod w taki sposób, aby nie przyprawiał on problemów podczas później modyfikacji. Odpowiednie nawyki mogą zaoszczędzić w przyszłości wiele czasu, nie mówiąc nawet o satysfakcji po stworzeniu prostego, czystego, ale w pełni funkcjonalnego kodu.

Tworzenie kodu dla aplikacji opiera się na szeregu zasad i wymogów danego języka. Każdy programista pisząc kod opiera się na pewnych ustaleniach lub na własnych nawykach. Powstają one od samego początku nauki języka i programowania ogólnie, warto więc zadbać o dobre praktyki jak najwcześniej. Tym bardziej, że prędzej czy później może przyjść praca w projekcie grupowym. Wszyscy uczestnicy programu muszą ze sobą współpracować i modyfikować swoją pracę. Szukanie i poprawianie linijek kodu wymaga jego schludności.

Nazywanie i sortowanie plików

Podczas pracy przy dużym projekcie przyjdzie pracować z dużą ilością plików, pogrupowaną na wiele sposobów. Spójność w nazwie klasy i jej pliku jest bardzo istotna. Do pliku ładowane powinny być rzeczy niezbędne do działania danej klasy. Nie tylko segregacja jest istotna, ale również jednoznaczne i wyczerpujące nazwy. Nawet jeśli miałoby to zająć nieco więcej czasu, to może on zaoszczędzić pracy w przyszłości. Nie tylko Tobie, ale i Twoim współpracownikom.

Nazewnictwo plików to bardzo istotna rzecz w ich późniejszym odnajdywaniu. Pliki powinny nazywać się zgodnie z przeznaczeniem. Ważne są tutaj pewne wzory nazw, np. klasy z mechanizmem pamięci podręcznej powinny nazywać się cache.class.php. W nazywaniu plików korzysta się ze znaków od a do z, z _ zamiast spacji oraz bez użycia dużych liter. Podobnie sprawa ma się z rozszerzeniami. Powinny iść w parze z przeznaczeniem, i tak inc.php używane będzie do includowania. Oznaczenie tpl wykorzystywane będzie w przypadku szablonu strony. Klasa testowa nazwana może być po prostu jako test.php.

Znaczniki PHP to kolejna rzecz, o której należy pamiętać. Powinny być w styku XML, czyli <?php na początku i ?> na końcu. Dzięki temu nie będzie trzeba w przyszłości ponownie edytować plików. Używanie stylu XML jest istotne, ponieważ jest funkcjonalna zawsze. Styl krótki czyli <? ?> działa tylko, jeśli short_open_tag jest o wartości 1, a w przyszłość może być już nieobsługiwany.

Standardy kodowania

Przykłady dobrych praktyk w nazywaniu plików

Poniżej znajduje się spis zagadnień i przykładów na odpowiednie porządkowanie i usprawnianie pisania kodu. Im wcześniej zaczniesz stosować dobre praktyki programowania tym lepiej, ponieważ nie zdążysz wyrobić sobie złych nawyków, prowadzących do niedbale rozpisanych aplikacji.

Nagłówek pliku

Jeśli korzystasz z narzędzi PHPDocumentator, Doxygen lub Javadoc, nagłówek pliku powinien wyglądać według przykładu:

<?php
/**
*
* @author Pierwszy autor persona1@example.com
* @author Drugi autor persona2@example.com
*
* @package Nazwa paczki
* @version $Id:$
* @copyright (c) 2009 Nazwa Twojej grupy/projektu
* @license http://creativecommons.org/licenses/by-sa/3.0/pl/
*
*/ ?>

Definicje wstępne

Kiedy znajdziesz się w sytuacji definiowania stałych już na początku pliku, zaraz za nagłówkiem, możesz skorzystać z takiego rozwiązania:

<?php
/**
* {HEADER}
*/
/**
* @ignore
*/
define("PIERWSZA", true);
define("DRUGA", false);
?>

Stałe

Aby uniknąć kolizji stałych między sobą, należy unikać korzystania z __ na początku i na końcu. Przykład złego użycia:

__FILE__, __LINE__.

Apostrof zamiast cudzysłowia

Ilekroć istnieje taka możliwość należy używać apostrofu zamiast cudzysłowia. Powoduje to szybszą pracę.

Przykłady dobrych praktyk w nazewnictwie zmiennych

Odpowiednie nazewnictwo zmiennych jest ważne, ponieważ umożliwia to orientację w kodzie i jego znaczeniu. Najlepiej pokazać to na porównaniu złego i dobrego przykładu stosowania nazw zmiennych. Przykład złego użycia nazw zmiennych:

<?php
$currentuser;
$currenttime;
$externalvariable;
$CurrentUser;
$CurrentTime;
$ExternalVariable;
$Current_User;
$Current_Time;
$External_Variable;
?>

Przykład dobrego użycia nazw zmiennych:

<?php
$current_user;
$current_time;
$external_variable;
?>

Odpowiednie nazywanie nośników danych to sposób na szybkie przemieszczanie się w kodzie. Przykłady złego i dobrego nazewnictwa:

<?php
$current_date_and_time;
?>

Dobre nazewnictwo:

<?php
$now;
?>

Język

Odpowiednie nazywanie zmiennych jest ważne dla szukania lub poprawiania już istniejących zmiennych. W językach programowania oraz w komunikacji z deweloperami zza granicy najczęściej wykorzystywanym językiem jest angielski. Nazwy funkcji powstały przecież ze skróconych określeń danych operacji. Przykładowo strrev() oznacza string reverse, odpowiedzialne za odwrócenie ciągu. Język angielski jest uniwersalny i właściwie każdy programista powinien go znać. Tłumaczenie kodu na inny język byłoby uciążliwe i niepraktyczne.

Zasady pisowni

PascalCase to zasada, według której każdą pierwszą literę pisze się dużą literą, np. AppendDeviceConnection. CamelCase z kolei twierdzi, że pierwsza litera jest mała, a kolejne pierwsze litery słów są duże, np. setConnection. Według notacji węgierskiej nazwy zmiennych i obiektów poprzedza się małą literą lub literami określającymi jej rodzaj. W języku PHP jest to raczej rzadko spotykana forma i dlatego niezalecana. Według tej zasady jednak pola prywatne klasy powinny być poprzedzone _ lub powinny znajdować się przed nazwą pola klasy niezależnie od operatora widoczności. Zasada ta jest stosowana głównie w C++.

W kwestii poprawności językowej warto również wspomnieć o unikaniu pisania koło siebie podobnych liter do cyfr i na odwrót. Może to prowadzić to błędów lub zwyczajnie utrudniać rozpoznanie znaków. Przykład złego zapisu:

<?php
$lO1 = "1I";
?>

Duże i małe litery

Niektórzy twierdzą, że wprowadzenie dużych liter może poprawić optymalizację, czyli zamiast $external_variable jest $external_Variable. Jednak wydaje się to być nadmiernym wysiłkiem, ponadto zmiana litery na dużą sprawia, że zmienne nie są równoznaczne.

Skróty

Kolejnym zagadnienie jest korzystanie ze skrótów. Ich używanie jest wskazane, jeśli tylko możliwa jest pisownia łatwa do rozszyfrowania. Dla przykładu Show UserInterface może być skrócone do ShowUI. Zmniejsza to objętość kodu i ułatwia jego pisanie.

Odstępy

Dla estetyki i czytelności niektórzy stosują odstępy od zmiennych, w których szereguje się do znaku równania. Koncepcja pali na panewce, kiedy nagle pojawi się zmienna dłuższa od poprzedniej najdłuższej i wszystkie odstępy należy poprawić.

<?php
$x                           = array("a", "b", "c");
$bardzo_bardzo_dluga_zmienna = array_flip($x);
$krotka_zmienna              = "whatever";
?>

Nazewnictwo funkcji, klas i metod

Podobnie jak nazwy klas powinny oddawać to, czym się zajmują, tak sam o powinno być pośród funkcji i metod. Zamiast pisać show_member_status(), powinno się napisać get_status(). W nazywaniu klas powinno się używać rzeczownika w liczbie pojedynczej, czyli Member zamiast Members.

Tablice

W sytuacji, gdy elementów tablicy nie ma dużo, można wymienić je po przecinku:

<?php
$cos_tam = array(1, 6, 9, 4, 5, 3);
?>

Natomiast inaczej, gdy jest ich dużo:

<?php
$krzywe_bity = array("pierwszy" => "lewy",
"drugi" => "płaski",
"trzeci" => "długi");
?>

Definiowanie funkcji, klas i metod

Dyrektywa global powinna znaleźć się na początku funkcji lub po if, jeżeli zmienna globalna ma być wykorzystana tylko w danym fragmencie funkcji. W poniższym przykładzie pomiędzy global a instrukcją warunkową jest odstęp taki sam, jakby była tam definicja zmienna tablica.

<?php
function nowy_ciag($str) //
{
global $config;
if(strlen($str) > 0)
{
return $config["hash"].$str.date("H");
}
else
{
return null;
}
}
?>

W definiowaniu metod stosuje się podobną zasadę z public, private i protected, zgodnie z ich przeznaczeniem. Metody magiczne przychodzą na początek klasy. Przykład:

<?php
class example
{
$memory = null;
public function calc() { /* Ciało metody */ }
protected function load_config() { /* Ciało metody */ }
private function add_event() { /* Ciało metody */ }
}
?>

Nazewnictwo argumentacji funkcji i metod powinno odzwierciedlać ich naturę. Przykład:

<?php
function auth($username, $password) { }
?> 

Zamiast tego:

<?php
function auth($a, $b) { }
//

lub

function auth($name, $pass) { }
?>

Komentarze

Komentarze są gorąco zachęcane w dobrych praktykach. Nie należy się ich wstydzić ani unikać. Mogą tylko ułatwić pracę przy kodzie. Jednak i tutaj obowiązuje odpowiednia pisownia. Jako separacji można użyć wieloliniowego /* */ lub jednoliniowego //.

<?php
# MySQL
$config["mysql"]["host"] = "localhost";
$config["mysql"]["database"] = "database";
$config["mysql"]["login"] = "prosty_login";
$config["mysql"]["password"] = "trudne_haslo";
$config["mysql"]["prefix"] = "no_i_prefiks_";
# Dir config
$config["dir"]["langs"] = "langs"; // Folder with langs files
$config["dir"]["logs"] = "logs"; // Folder with any logs
?>

Wcięcia

Wcięcia nadają estetycznego wyglądu i poprawiają czytelność kodu. Standardowo używa się 4 spacji jako wcięcia, ale używanie jednej spacji spowoduje, że kod będzie bardziej zbity i łatwiejszy w ogarnięciu jednym rzutem oka.

<?php
// początek wcięcia podstawowego
// początek wcięcia poziomu pierwszego
// początek wcięcia poziomu drugiego
do_something();
// koniec wcięcia poziomu drugiego
// koniec wcięcia poziomu pierwszego
// koniec wcięcia podstawowego
?>

Struktury kontrolne

W strukturach kontrolnych zawarte są instrukcje warunkowe if, for, while, switch i inne. Poniżej przykład odpowiedniego zapisu:

<?php
if($a && $b)
{
}
else if(!$a || $b)
{
}
else
{
// default
}
if($c)
{
if($d)
{
}
else
{
}
}
switch($condition)
{
case "one":
do_something();
do_something_else();
break;
case "two":
case "three":
exit;
break;
default:
break; // Dla czystości sumienia można dodać Smile
}
?>

Oraz przykład złej pisowni, z zaznaczonymi błędami:

<?php
if ($a && $b) // Niepotrzebnie zrobiony odstęp
{
}
else if(!($a) || $b) // Niepotrzebnie użyty nawiasy
{
}
if($c)
{
if($d) do_something(); // Brak klamer
}
switch($condition)
{
case "one":
do_something(); // Brak wcięcia
do_something_else(); // Jak wyżej
break;
case "two": case "three": // Warunki w tej samej linijce
exit; // Brak wcięcia
break;
}
?>

Nawiasy klamrowe i instrukcje sterujące

Istnieje wiele sposobów pisania instrukcji warunkowych, klas, funkcji czy pętli.

Styl BSD

W stylu BSD nawias otwierający jest w wierszu po warunku, a oba nawiasy są wyrównane do lewej strony słowa kluczowego:

<?php
if ($condition)
{
// Instructions
}
?>

Styl GNU

Nawias otwierający jest w kolejnym wierszu i jest wcięty o połowę wcięcia:

<?php
if ($condition)
{
// Instructions
}
?>

Styl K&R

Styl pochodzący od nazwisk Kerninghan i Ritchie, autorów książki pt. „Programowanie w języku C”:

<?php
if ($condition) {
// Instructions
}
?>

Styl Wishart (Whitesmiths)

Styl powstał z rąk autorów pierwszego komercyjnego kompilatora języka C:

<?php
if ($condition)
{
do_something();
}
?>

Grupowanie słów

Dla zwiększenia czytelności kodu można grupować wyrazy, ale w sposób umiejętny. Poniżej przykład dobrego grupowania:

<?php
if(!($object instanceof class_name))
{
}
?>

Przykład złego grupowania razem ze złymi odstępami między nawiasami oraz nawiasem przed każdym wykrzyknikiem:

<?php
if( !( $a ) && $b )
{
}
?>

Typ zmiennej i rzutowanie

Ponieważ język PHP rzutuje dane niejawne, należy odpowiednio dobierać operatory porównania:

<?php
$boolean_var = true;
$string_var = "true";
$other_var = null;
if($boolean_var)
{
if($string_var == true)
{
if($other_var == false)
{
echo "O really?";
}
}
}
?>

Pętle

Istnieją trzy sposoby zapisywania pętli, różnice polegają na nazewnictwie kursora elementu. Pierwszym jest zaczynanie od $h, drugim zaczynanie od litery $i, trzecim od $a.

<?php
for($h = 0; $h < $first_size; ++$h)
{
for($i = 0; $i < $second_size; ++$i)
{
for($j = 0; $j < $third_size; ++$j)
{
// Do something!
}
}
}
?>

Poniżej przykłady odpowiednich pętli foreach() i while():

<?php
foreach($some_array as $key => $value)
{
}
?>
<?php
$h = 1;
while($h < 10)
{
echo ++$h;
}
?>

Wszystkie te wskazówki mają na celu usprawnienie pisania kodu, ale również poprawę jakości tego kodu i w efekcie pracy grupowej. Czasami pewne nawyki na początku mogą wydłużać pisanie, ale w efekcie pracując przy modyfikacji odzyska się czas i będzie ona znacznie ułatwiona. Dobre praktyki oznaczają również obieranie drogi zdroworozsądkowej i wybranie odpowiedniego sposobu pisowni. Być może nie ma twardych zasad ani idealnego kodu, ale każdy rozpozna i doceni schludnie napisaną aplikację. Im szybciej nabierzesz dobrych nawyków, tym lepszy warsztat będziesz kształcić, ale co ważniejsze – przekazywać dalej.

Cyfrowe newsy / Bądź na bieżąco

Od początku 2022 roku wchodzimy w skład Unity Group. Teraz zapisując się do naszego newslettera, będziesz na bieżąco z informacjami całej naszej organizacji.

    Wypełniając formularz wyrażasz zgodę na wysyłkę newslettera przez Unity S.A. z siedzibą we Wrocławiu. Zgodę możesz wycofać w każdej chwili. Więcej informacji na ten temat znajdziesz w naszej polityce prywatności.

    *Wymagane

    Andrzej-kurs-programowania

    Andrzej Szylar

    Chief Executive Officer

    E-mail:

    a.szylar@global4net.com
    Magda2

    Magdalena Paczyńska-Kamienik

    HR Manager

    Aleksandra

    Aleksandra Bielawska-Clegg

    HR Business Partner

    E-mail:

    Michal

    Michał Duława

    New Business Developer

    E-mail:

    Katarzyna

    Katarzyna Zajchowska

    Marketing Partner

    E-mail: