Funksiyalar

Funksiyalar istənilən proqramın əsas hissəsidir. Ona görə onları yaxşı şəkildə yazmaq bizim əsas vəzifələrimizdən biri olmalıdır. Əgər siz funksiyaya ötəri baxdıqda çoxlu əməliyyatlar, kod təkrarı və qarmaqarışıqlıq görürsünüzsə bu nələrinsə yanlış getdiyinə işarədir.

Yığcam

Yaxşı funksiyanın ilkin şərti yığcam olmasıdır. İkinci şərt isə odur ki, funksiya ilkin şərtdə qeyd olunandan daha yığcam olmalıdır.
Bəs görəsən yığcam və ya kiçik həcmli funksiya dedikdə biz nəyi nəzərdə tuturuq ? İdeal halda funksiya 2, 3 və ya 4 sətrdən ibarət olmalıdır. Mənim fikrimcə 10 sətrdən artıq metodları parçalamağı düşünməliyik.

Bir işi görmə

Hər bir funksiyanın işi yalnız bir işi görmək olmalıdır. Birdən artıq iş görən funksiyanı parçalamağı düşünməliyik.

FUNKSİYALAR BİR İŞİ GÖRMƏLİDİR. ONLAR BU İŞİ YAXŞI ŞƏKİLDƏ GÖRMƏLİDİR. ONLAR YALNIZ BU İŞİ GÖRMƏLİDİR.

Burada da əsas məqam odur ki, biz bir iş dedikdə nəyi nəzərdə tuturuq ? Bu bir az geniş anlayışdır, qısa şəkildə izah edəsi olsaq, əgər biz verilmiş funksiyanı bir neçə adından nə etdiyi bəlli olan kiçik hissələrə bölə biliriksə bu o deməkdir ki, bu funksiya artıq bir deyil bir neçə işi görür.

Switch ifadələri

Switch ifadələrindən istifadə etməklə balaca funksiyalar yazmaq çox çətindir. Həmçinin switch ifadələrindən istifadə etməklə yalnız bir işi görən funksiya yazmaq da bir xeyli çətin işdir. Öz təbiətindən asılı olaraq switch ifadələri həmişə bir deyil, N işi görürlər. Təəssüflər olsun ki, biz həmişə switch ifadələrindən yayına bilmirik, lakin polimorfizmdən istifadə edərək əmin ola bilərik ki, hər bir switch ifadəsi daha aşağı səviyyəli klas vasitəsi ilə ifadə oluna bilir.

Funksiya arqumentləri

İdeal halda funksiya heç bir arqumenti olmayan (0-niladic) funksiyadır. Növbəti bir arqumentli - monadic və iki arqumentli - dyadic funksiyalar gəlir. 3 arqumentli - triadic funksiyalardan mümkün qədər yayınmaq lazımdır. 3-dən artıq arqumentli funksiyalar - polyadic xüsusi əsaslandırma tələb edir və heç bir halda istifadə edilməməlidir.
Arqumentlər test etmə nöqteyi nəzərindən də qəlizidir. Təsəvvür edin ki, arqumentlərin sayı nə qədər çox olsa, sizin testlərdə mümkün kombinasiyaların sayı da o qədər çox olacaqdır. Əgər yalnız 1 arqument varsa, bu proses çox da çətin olmayacaqdır. 2 arqumentli halda iş bir az qəlizləşəcək, 2-dən daha artıq arqumenti olan funksiyalar üçün isə hər bir mümkün kombinasiyanı yoxlamaq baş ağrısından başqa bir şey olmayacaqdır.
Bundan əlavə output arqumentləri funksiyanın başa düşülməsini çətinləşdirir və mümkün qədər bundan yayınmaq lazımdır. Biz funksiyaya baxanda ilk baxışdan arqumentlərin giriş tipli olmasını fərz edirik və geri döndəriləcək informasıyanın output arqumentləri vasitəsi ilə olacağını gözləmirik.

"Flag" tipli arqumentlər

Funksiyaya boolean tipli arqument ötürmək çox pis bir yanaşmadır. Bu ilkin baxışdan funksiyanın arqumentin doğru və ya yanlış qiymətindən asılı olaraq 2 işi gördüyünü bizə aşılayır. Bu şəkildə funksiyaları 2 hissəyə bölməli və o şəkildə istifadə etməliyik

Yan təsirlərin olmaması

Bu o deməkdir ki, sizin yazdığınız funksiya bir işi görməlidir və bu funksiya öz içərisində hansısa gizli xüsusiyyətləri saxlamamalıdır. Məsələn tutaq ki, bizim checkUsernameAndPassword adlı funksiyamız var, bu funksiya daxil edilmiş məlumatlar əsasında bizə true və ya false dəyər qaytarır. Əgər bu funksiya məsələn verilmiş məlumatların doğru olması halında hər hansı sessiya məlumatlarını dəyişdirirsə onda bu yan təsir sayılır. Funksiyanın adı isə bizə bu yan təsirin olmasını göstərmir.

Sorğu və əmr ifadələrinin ayrılması

Funksiyalar ya sorğu icra etməli və ya da sorğuya cavab verməlidir, lakin eyni anda hər ikisini yox, yəni funksiya ya obyekt haqqında məlumat geri döndərməli və ya obyektin vəziyyətini dəyişməlidir. Hər ikisinin eyni anda edilməsi qarışıqlığa səbəb ola bilər.

Exception - ların idarə olunması

try/catch bloklarından istifadə kodu onsuz da qarışıq formaya salır, yəni biznes məntiqi ilə error-ların idarə olunması məntiqi bir birinə qarışır. Ona görə yaxşı olardı ki, try/catch blokları ayrıca funksiyaya alınsın və biznes məntiqindən ayrı tutulsun. Funksiya bir iş görməldir və error-ların idarə olunaması da bir işdir, ona görə error-ları idarə edən funksiya digər işləri görməməlidir.
Həmçinin funksiyaların error kodlar döndərməsindənsə bu hallarda exception atması daha məqsədə uyğundur. Çünki əks halda bu funksiyanın çağırıldığı hissələrdə if ifadələri vasitəsi ilə iç-içə struktur yaranır.

Şərhlər

"Pis koda şərh yazmayın, onu yenidən yazın"
Düzgün yerdə istifadə edilmiş şərh nə qədər faydalıdırsa, yanlış, köhnə və çaşdırıcı şərh bir o qədər təhlükəlidir.

Şərhlər pis yazılmış kod üçün nəzərdə tutulmayıb

Şərh yazmaqda əsas motivasiyalardan biri onu pis yazılmış kod haqqında yazmaqdır. Beləki, biz hər hansı modul yazırıq və bilirik ki, bu çox çaşdırıcı və qarışıqdır. Ona görə biz öz-özümüzə deyirik ki, "Daha yaxşı olardı ki, mən bu koda şərh elavə etməklə vəziyyətdən çıxım". Lakin bu belə deyildir, bu halda yeganə çıxış yolu kodu ilk öncə təmizləmək, yəni strukturlu hala salmaqdır.

Özünüzu kodla ifadə edin

Aşağıdakı koda diqqət yetirək:

// Check to see if the employee is eligible for full benefits
if((employee.flags & HOURLYFLAG) && (employee.age > 65))

və ya

if(employee.isEligibleForFullBenefits())

İkinci kod parçası heç bir şərhə ehtiyac olmadan gördüyü işi adından bəlli edir.

Yaxşı şərhlər

Bəzən şərh yazmaq vacib və faydalıdır. Lakin nəzərə almaq lazımdır ki, əsl yaxşı şərh o şərhdir ki, bu şərhi yazmadan başqa cür vəziyyətdən çıxmaq qeyri mümkündür.

Aşağıda bəzi yaxşı şərhə nümünələr göstərək:

  1. Leqal şərhlər - Bəzən bizim korporativ kod standartlarımız bizə bəzi hissələrə leqal şərhlər əlavə etməyi məcbur edir. Buna misal olaraq müəlliflik və kopirayt şərhlərini göstərmək olar.
  2. İnformativ şərhlər - Buna misal olaraq məsələn yazılmış regular expression - nın hansı tip mətnlərə tətbiq olunduğu haqqında şərhi misal göstərmək olar.
  3. Aydınlatma - bəzən qarışıq gələn giriş arqumenti və ya return dəyərinin daha düzgün başa düşülməsi üçün şərh yazmağa ehtiyac duyuruq. Yaxşı olardı ki, bu zaman şərhə ehtiyac duymadan kodda olan qarışıqlığı aradan qaldıraq, lakin əgər bu arqument hər hansı dəyişə bilməyəcəyimiz kitabxanadan gəlirsə o zaman çıxış yolu kimi şərhlərdən istifadə edə bilərik.
  4. Nəticələr haqqında xəbərdarlıq - Buna misal olaraq məsələn hər dəfəsində çalışdırılanda 10-dəqiqədən artıq vaxt aparan bir unit test-ə yazılmış məlumatlandırıcı şərhi göstərmək olar.
  5. TODO şərhləri - Bəzən zamanla etməli olduğumuz işləri TODO şərhləri vasitəsi ilə ifadə etmək faydalıdır. Müasir IDE-lərin bir çoxunda bu tip şərhləri asanlıqla tapmaq mümkündür.

Pis şərhlər

Bir çox yazılan şərhlər bu kateqoriyaya aiddir. Bir çox halda bu tip şərhlər pis yazılmış kodlara, tamamlanmamış ifadələrə əlavə olunur ki, halbuki bu kod vasitəsi ilə ifadə oluna biləndir.

Aşağıda bəzi pis şərhlərə nümünələr göstərək:
1.Lazımsız şərhlər - Əgər siz şərh yazmaq istəyirsinizsə, o zaman əmin olmalısınız ki, bu şərh yazılan ən yaxşı şərhdir. Məsələn əgər try/catch blokundan istifadə ediriksə və catch blokunda heç bir iş görməyərək yalnız əlavə informasiya tipli şərh yazırıqsa və ya hər metodun başlığına bu metodun nə iş gördüyünü şərh şəkilində yazırıqsa bu lazımsız şərhlərə misal ola bilər.
2. XML şərhlər (C#) - Hər bir method və ya klas üçün xml şərhlər yazmaq və bu şərhlərdə xüsusi bir şey ifadə etməyərək, yalnız parametrləri sadalamaq bəzən sadəcə lazımsız bir işdir.
3. Küylü şərhlər - Məsələn konstruktorun üzərinə sadəcə bunun konstruktor olmasını yazmaq, adından nə etdiyi bəlli olan bir metoda şərh yazmaq və s. buna misal ola bilər.
4. Şərhə alınmış kodlar - Bəzən müvəqqəti olaraq bəzi kodları şərhə atarıq və uzun müddət bu bu şəkildə davam edər. Bu çox pis bir vrdişdir və bundan yayınmaq lazımdır. Əgər gələcəkdə bizə bu kod lazım olsa onu SCM - lər vasitəsi ilə əldə etmək mümkündür.
5. Çoxlu informasiya - Bəzən şərhlər o qədər uzun yazılır ki, şərhin özünü oxuyub başa düşmək kodu oxuyub başa düşməkdən daha qəliz olur. Bu tip şərhlərdən yayınmaq lazımdır.