Clean Code Prensipleri

CLEAN CODE-1

Kariyerime ilk başladığım şirkette ufak bir ekiple büyük ölçekli bir CMS uygulamasında geliştirmeler yapıyorduk. O zamanlar okulda ve kendi yaptığım projelerde öğrendiklerimin dışında ilk defa büyük ölçekli profesyonel bir projede kod yazıyordum. 1. senemin sonlarına geldiğimde ilk zamanlar geliştirdiğim kodlara geri dönüp baktığımda gözlerim kanıyordu  🙂 böylece sektördeki ilk teknik borçlanmalarımın geri ödemesini yapmaya karar verdim. Teknik bilgi ve tecrübelerine güvendiğim ekip arkadaşlarım ki emekleri yadsınamaz Kuthay Gümüş ve Ömer Korkmaz ile bunu paylaştım. Etkili ve planlı bir refactor için yol haritamızı belirledik kollarımızı sıvadık ve hep birlikte oturduk (yeri geldi sabahladık) kodlarımızı tek tek refactor etmeye başladık 🙂  Birlikte çıktığıımız bu büyük ölçekli refactor macerasını özellikle de bu süreçte izlenmesi gereken yolu ve daha önemlisi yapılmaması gerekenleri ekipçe deneyimlediğimiz kadarıyla bir başka yazımda detaylıca paylaşacagım 🙂 . Bu süreçte literatürü de biraz araştırıp clean code standartlarını öğrenmeye karar verdim ve sizlerin de incelemek isteyebileceği iki güzel ile birlikte görebildiklerimi ve faydalandıklarımı paylaşmak istedim. 

Pluralsight üyeliği olanlar için Clean Code: Writing Code for Human 
Kitap karıştırmayı sevenler için Clean Code A Handbook of Agile Software Craftsmanship

İşi biraz daha ileri taşıman isteyenler de Clean Architecture ve Clean coder kitaplarına da bakabilirler.

Konuya  Clean Code A Handbook of Agile Software Craftsmanship kitabının girişinden çok hoşuma giden, clean codingin önemini anlatan bir yazıyla başlayayım.

80’lerde bir şirket müthiş ve çok popüler bir uygulama yazdı. Ancak bir zaman sonra yeni sürüm çıkma (release) dönemleri uzamaya başladı. Bir sonraki sürümde hatalar çözülmemiş oluyordu. Yüklenme süresi uzuyor ve çökmeler artıyordu. Büyük bir hüsran ile uygulamayı kaldırdığım günü hatırlıyorum. Zaten bir zaman sonra da şirket tamamen piyasadan çekildi.

20 yıl sonra şirketin ilk çalışanlarından biri ile karşılaştım ve ona ne olduğunu sordum. Cevabı korkularımı doğruladı. Ürünü markete erkenden sürebilmek için çok acele etmiş ve kodda çok büyük bir kargaşaya sebep olmuşlardı. Daha fazla özellik ekledikçe, kod daha da kötü bir hal almış ve o kadar kötü hale gelmişti ki, artık kodu yönetemiyorlardı. Böylece kötü kod şirketin kapanmasına sebep olmuştu.

Hepimiz zaman zaman geri dönüp kodumuzu temize çekeceğimizi söylemişizdir. Ancak o zamanlar LeBlanc’ın şu kuralını bilmiyorduk: “Sonra asla demektir (Later equals never).”

Kod karmaşıklığı arttıkça takımların verimliliği düşer ve sıfıra yaklaşır. Verimlilik düştükçe de yöneticiler yapabildikleri tek şeyi yaparlar; verimliliği artırması umudu ile projeye daha çok insan kaynağı eklerler. (İnsan kaynak mıdır yoksa değer mi?) Takımdaki herkes verimliliği artırmak için büyük baskı altındadır. Öyle ki verimliliği sıfıra daha da yaklaştıracak şekilde kod karmaşası yaratmaya devam ederler.

Bu kısa anlamlı hikayeden sonra clean kodun çekirdek prensiplerine geçebiliriz diye düşünüyorum. Bu yazımda belli kaynaklardan ve deneyimlerimden derlediğim, kod yazarken ufak dokunuşlarla kodu daha temiz ve okunulabilir kılmak adına bazı yöntemlerden bahsetmeye çalışacağım.

1. Sınırları belirleme

Ölçeği büyük projeler geliştirirken javascript, html, css, C#, sql gibi bir çok teknololojiyi bir arada kullanmamız gerekebilir. Ancak bu teknolojilerin her birinin söz dizimi ve yapısı farklıdır. Bu sebeple kullandığımız teknolojilerin sınırlarını belirlememiz gerekir. Bu da bize daha okunaklı, bakıma ve geliştirmeye açık kod yazma imkanı sunar.

Eğer ki bir projede javascript, html, css, C#,  sql gibi teknolojileri bir arada kullanıyorsak, dikkat etmemiz gereken nokta, her teknolojinin kendisine ait uzantılı dosyada tutulması gerektiğidir. Javascriptlerimiz .js  uzantılı, csslerimiz .css uzantılı, htmller .html uzantılı, C# kodları .cs uzantılı dosyalarda ve sql kodları da uygun bir yapıda soyutlanmış olmalıdır.

2. İsimlendirme

İsimlendirme konusu kulağa çok basit bir konu gibi gelse de yazılım geliştirmenin en önemli noktalarındandır. Anlamsız veya kısaltmalarla verilen isimler bir süre sonra kodun okunurluğunu azaltarak kodu anlayacak kişiye zaman maliyeti olarak dönecektir.  Aynı şekilde anlamlı ve doğru verilen isimler yazılımcının işini inanılmaz derecede kolaylaştırabilir. Normal şartlarda, bir fonksiyonu ismiyle değişkenleriyle yapılan işlemleri vs ile yukardan aşağıya bir kitap okur gibi okuyup anlamlandırabiliyor olmamız gerekir. Bu tip kodlar yorum satırlarına da nadir olarak ihtiyaç duyarlar ve self-documented kod olarak isimlendirilirler.

2.a Class İsimlendirmeleri

Tanımlayacağınız classın single responsibilty prensibine uygun olması ve isminin de bu single responsibility’i net bir biçimde yansıtıyor olması gerekir. İyi isimlendirilmiş classlar genelde isim olarak bir fiil değil bir isim alırlar. Classlar, nesnelerini üretebildiğimiz yapılar olduğundan bir class isimlendirirken kendinize sormanız gereken soru, bunun nesnesini üretmek OOP’ye göre kulağa mantıklı geliyor mu? olmalıdır.

                        Dirty                                    Clean                                      
                        WebsSiteBO                               User
                        Utilty                                   Account
                        Common                                   QueryBuilder
                        MyFunctions                              ProductRepository
                        JimmysObjects
                        Manager, Processor,Info

2.b Method İsimlendirmeleri

Kötü bir metot isimlendirmesi okunduğu zaman, metodun ne iş yaptığına dair kafa karışıklığı yaratır. İyi isimlendirilmiş metodun ismini okunduğunda da metodun gövdesini dahi okumadan ne iş yaptığı anlaşılır ve kullanılabilir. Metotlar bir fonksiyonelliği yerine getirdiklerinden isimleri ‘fiil’ olmalıdır.

Metotlar da classlar gibi single responsibilty prensibine uymalı ve sadece tek bir fonksiyonelliği yerine getirmelidir. Metot isimlendirmesinde And, If, Or, gibi bağlaçlar geçiyorsa orada durup metot birden fazla işi içerisinde barındırıyor mu diye bir düşünmeniz gerekli.

                            Dirty                           Clean                                               
                           Getprocess                  GetRegisteredUsers
                           pending                     IsValidSubmission
                           dolt                        ImportDocument
                           start                       SendEmail
                           On_init
                           SaveAndPublish

3.b Kısaltma kullanımı 

İsimlendirmelerde kısaltma kullanımı kodlamada yapılan en büyük yanlışlardandır. Bir geliştiricinin yazdığı kodu başka bir geliştirici okurken kitap okur gibi ne yazıldığını anlayabilmelidir. Burdan yola çıkarak kitap okurken, kitaptaki isimlerin kendilerini değil de kısaltmalarını görseniz sizin için de çok anlamlı olmazdı.

                           Dirty   : regUser, registUser, RegisUser..

4.b Booean isimlendirmeleri

İyi bir boolean isimlendirmesi okuyucuya sanki cevabı “doğru” veya “yanlış” olan bir soru soruyormuş gibi olmalıdır.

                             Dirty                          Clean
                             open                          IsOpen
                             start                         done
                             status                        isActive
                             login                         loggedIn

3. Conditionlar

  • Booelan bir değeri condition içerisinde tekrar true ya da false’a eşitlemek gerek olmayan bir kalabalık yaratacaktır onun yerine aşağıdaki kullanımı tercih etmeliyiz.
                                Dirty                             Clean
                          if(loggedIn==true)                    if(loggedIn)
                          {}                                    {}
  • Boolean değişkenlere true false atamalarında dikkat etmemiz gereken nokta, elimizdeki değişkene sonucu aşağıdaki gibi direkt olarak bu boolean üzerinden atayabiliriz. Böylece aşağıda olduğu gibi  8-9 satırlık kodu tek satırda yazabiliriz.
                           Dirty                                                                                                         
                  bool goingToChipotleForLunch;

                 if(cashInWallet>60)                                         Clean
                 {
                   goingToChipotleForLunch=true;                bool goingToChipotleForLunch = cashInWallet>6.00
                 }
                 else
                 {
                   goingToChipotleForLunch=false;
                 }

                 int regisrationFee;
                 if(isSpeaker)                                    int registrationFee = isSpeaker ? 0 : 50;
                 { registrationFee=0;}
                 else
                 {registrationFee = 50;}
  • Koşul cümlelerinde ters koşul kullanmak da kodu okuyanlar için kafa karışıklığı yaratmaktadır. Elimizden geldiğince pozitif anlamlı koşullar üzerinden ilerlemeliyiz.
                 Dirty                                            Clean
             if(!isNotLoggedIn)                              if(loggedIn)
  • Bir grup seçenek arasından seçim yapacaksak bunu static olarak vermektense enumlara bağlayıp kullanmak daha yerinde olacaktır. Böyleyce kodda ilgili bir opsiyonu değiştirmek istediğimizde, o opsiyonun kullanıldığı yerleri tek tek bulup değiştirmek yerine, ilgili enum opsiyonunu değiştirmemiz yeterli olacaktır.
                    Dirty                                          Clean
            if(employee=="Manager")                   if(Employee == EmpoyeeType.Manager)
  • Kodun içerisinde hiç bir anlam ifade etmeyen sayı, string gibi staticleri de direkt olarak kullanmamamız gerekir. Aşağıda age > 21 koşulu bize yaşın 21’den büyük olması durumunu net bir şekilde anlatıyor ancak 21’in ne ifade ettiği ve neden orada olduğu konusunda bir fikrimiz yok. Değişken çok yerde kullanılıp belli aralıklarla değiştirilmeyecek ise database’de tutmak yerine aşağıdaki şekilde bir tanımlama koda anlam katacaktır.
                   Dirty                                          Clean     
                 if(age>21)                                int legalDrinkingAge=21;       
                                                           if(age>legalDrinkingAge)     
  • Kompleks koşullar okunurken kafa karışıklığı yaratır. Örneğin aşağıdaki gibi bir koşulun hem takip edilmesi hem de ne amaçla oraya konulduğunu anlamak oldukça zordur. Ancak unutmamamız gereken şey,  her boolean ifade ve bunu içerisinde barındıran her koşul aslında cevabı true ya da false olan bir soruya cevap verdiğidir ve bu sorunun cevabına göre koşul değerlendirilir. Bunu göz önünde bulundurarak elimizdeki kompleks koşulların hangi soruya cevap verdiğine istinaden bir değişkene atamamız veya fonksiyonlaştırmamız işimizi oldukça kolaylaştıracaktır.
      Dirty                                                                                                   
      if(employee.Age>55 && empoyee.YearsEmployed>10 & employee.IsRetired==true)         

      Clean
      bool eligibleForRetirement=  employee.Age > minRetirementAge && 
                                   employee.YearsEmployed > MinPensionEmployementYears && 
                                   employee.IsRetired;

      if( eligibleForRetirement )

veya

    Dirty
    
    if(fileExtension=="mp4" || fileExtension =="mpg"  || fileExtension == "avi")     


    Clean
                                                                                                                
    private bool ValidFileRequest(string fileEtension)
    {
       return (fileExtenion=="mp4" || fileExtenion=="mpg" || fileExtension=="avi"); 
    }

    if( ValidFileRequest(fileExtension) )
  • Yazılımcılar olarak kodları çok sevsek de bazen her şeyin cevabı kod olmayabiliyor. Elimizde, belli değerlere karşı belli sonuç döndüren bir yapı olduğunu varsayalım. Bunu hard-coded olarak kod içerisinde tutmaktansa, database’de bir tabloda json formatında veya key value şeklinde tutup ilgili key’e ilgili value’yi dönen bir fonksiyon üzerinden yürüyebiliriz.
        Dirty
      if(age<20)
        return 345;
      else if(age<30)                              Clean    
        return 419;                             return Repository.GetInsuranceRate(age);
      else if(age<40)
        return 476;
      else if(age<50)
        return 516;
  • Validasyonları iç içe if kullanarak yapmak çoğu yazılımcının düştüğü bir yazım yanlışıdır. Bu şekilde bir validasyon zincirinin okunması ve aynı zamanda hangi ifin hangi else denk geldiğinin anlaşılması zordur. Bunun yerine ifleri alt alta sıralayıp ilk yakalanan validasyondan itibaren kodu return etmek daha doğrudur.
          
                        Dirty                                             Clean
                          if()
                            if()                                         if()  return;
                              if()                                       if()  return;
                               if()                                      if()  return;
                                  do something...                        if()  return;   
                                 else                                      do something...
                                    return;
                               else
                                 return;
                             else
                              return;
                           else
                            return;

4. Fonksiyonlar

4.a Kod tekrarından kurtulmak

Dry(dont repeat yourself) çoğu yazılımcının duyduğu bir kod prensibidir. Bir fonksiyonelliği kodun birden fazla kısmında tekrar eden bir şekilde yazdıysanız ve daha da kullanmaya ihtiyaç duyabileceğiniz potansiyelde bir kod ise bu kod parçacığını metotlaştırmalısınız demektir.

4.b Olabildiğince Küçük..

Fonksiyon yazarken göz önünde bulundurmamız gereken en önemli kriterlerden birisi fonksiyonların olabildiğince küçük olmasıdır.  Bir fonksiyon 100’lerce satırdan oluşmamalıdır en fazla 20 satırda fonksiyonu tamamlarsanız tadından yenmez. Eğer fonksiyonunuz satır sayısı gitgide artıyorsa ve siz de hala yazmaya devam ediyorsanız, orada durup bu fonksiyonu daha küçük parçalara nasıl ayırırım diye bir düşünün derim 🙂

4.c Yalnızca tek işlev

Her fonksiyon yalnızca bir işlevselliği gerçekleştirmeli ve bunu da en efektif şekilde gerçekleştirmelidir. Fonksiyonu yazan yazılımcı da onu ileride çağıracak olan yazılımcı da o fonksiyonu tek ve spesifik bir amaç için çağırmalıdır ki bu da fonksiyonun isminden net bir şekilde anlaşılabilmelidir. Sonuçta önceden yazılmış bir fonksiyonu kullanırken tekrar tekrar kodlarını kontrol edemeyiz ve kimse adından yola çıkarak çağırdığı bir fonksiyonun arkada öngöremeyeceği hareketler yapmasını istemez 🙂

4.d Niyeti net bir şekilde belli etmek

Koşul ifadelerinin içerisindeki koşulları programatik olarak çoğu zaman anlarız ancak neden o şekilde yazıldığını altında yatan anlamı tam olarak anlayamayız. Örnek üzerinden ilerlersek aşağıdaki kirli kod örneğinde koşul yapısı bize fileExtension’un mp4, mpg veya avi olması gerekiğini ve isAdmin veya isActive’İn true olması gerektiği net bir şekilde gösteriyor ancak hem bu ifadelerin altında yatan anlamı tam olarak göstermiyor hem de kodu okuyan geliştiricinin işini zorlaştırıyor.

        Dirty
       if(fileExtension ==  "mp4" || fileExtension =="mpg" || fileExtension =="avi" && (isAdmin || isActive))

Aşağıdaki kod örneği ise koşul yapısının amacını net olarak belli eden ve geliştiricinin rahatlıkla okuyup anlayabileceği kod örneğidir.

        Clean

       private bool ValidFileRequest(string fileExtension, bool isActiveFail, bool isActive)
       {
          var validFileExtensions = new List<string>() {"mp4","mpg","avi"};
  
          bool IsValidFileType = validFileExtensions.Contains(fileExtension);
          bool IsUserAllowedToViewFile = isActiveFile || isAdmin;

          return IsvalidFileType && IsuserAllowedToViewFile;
       }
  
       if(ValidFileRequest(fileExtension, active))
  • Clean kod yazarken kullandığımız dilin bize verdiği nimetlerden de yararlanmalıyız. Örneğin aşağıdaki iki kod parçacığı da aynı işi yapmakta ancak ilk kodun 5 satırda yaptığını ikinci kod tek satırda yapmakta ve ne yapmak istediği de çok net bir şekilde anlaşılabilmektedir.
    Dirty

    List<User> mathcingUsers = new List<User>();
     
    foreach(var user in users)
    {
       if(user.AccountBalance<mininmumAccountBalance && user.Status == Status.Active)
       { matchingUsers.Add(user);}
    }

     return matchingUser;

     Clean

     return users.Where(u=> u.AccountBalance < mininmumAccountBalance && u.Status == Status.Active);

4.e Parametre sayısı

Bir fonksiyonda çok fazla parametre olması sıkıntılı bir durumun işaretçisi olmakla birlikte fonksiyonun yapması gerekenden fazla iş yaptığının da habercisi olabilir. Fonksiyon yazarken parametre sayısını mümkün oldukça 0-2 arasında tutmaya gayret etmeliyiz.

Aşağıdaki kirli kod örneğinde metot fazla parametre almış ve User tipinde bir user, email gönderilip gönderilmeyeceğini belirleyecek olan bool bir sendEmail parametresi, emailFormatı, rapor yazdırılıp yazdırılmayacağını belireyecek olan bool printReport ve işin faturalandırılıp faturalandırılmayacağını belirleyen bool sendBill parametresi. Parametrelere bakıldığında dahi metodun yapması gerekenden daha fazla iş yaptığı rahatlıkla anlaşılmaktadır.

        Dirty
        public void SaveUser(User user, bool sendEmail, int emailFormat, bool printReport, bool sendBill)

Boolean parametreler flag argument olarak değerlendirilir. Genelde fonksiyonun birden fazla iş yaptığını belirtir.

Aşağıda fonkisyonun aldığı iki parametreden yapması gerekenden fazla iş yaptığı anlaşılmaktadır. SaveUser metodu kaydedeceği kullanıcıyı almakta, bool emailUser ise bu user kaydedildikten sonra email atılıp atılmayacağını belirlemektedir. Email atma işi kullanıcıyı kaydetme işinden farklı bir iş olup farklı bir fonksiyonda farklı bir çağırımla gerçekleştirilmeli ve single responsibilty prensibine uyulmalıdır.(Side effect)

       Dirty
       private void SaveUser(User user, bool emailUser)
       {
           if(emailUser)
           { yolla }
       } 

       Clean
       private void SaveUser(User user)
       {
         //save user
       }
       private void EmailUser()
       {
         //email user
       }

5. Exception Handling

  • Tanımladığınız exceptionlar, hatanın yeri ve kaynağı hakkında detaylı bilgi içermelidir. Bunun için exceptionlarımıza ve loglarımıza açıklayıcı hata mesajları eklemeliyiz.
  • Hataları yutmamalısınız. 1 sene kadar önce çalıştığım şirkette geliştirilen bir uygulama ilk 2 3 hafta kusursuz çalıştı. Bu süre boyunca ufak bir hata bile vermedi. Tabi ekipte uygulamayı  yazan kişiye takdirler tebrikler de havada uçuştu 🙂 . Bir noktada verileri kontrol edince tamamen tutarsızlıklarla dolu olduğunu gördük. Kodu açıp baktığımızda gördüğümüz şey bizim için sürpriz olmuştu. Tüm fonksiyonlar try catch içerisinde ve olası tüm hatalar loglanmadan ve bir uyarı verilmeden yutulmuş 🙂 . Error handling yaparken hataları yutmamaya özen gösterin. Exceptionu fırlatın fırlatın ki hata olduğunda anında o hata hissedilip çözülsün. Loglamayı da unutmayın tabi 🙂
  • Try-catch ile exception yönetirken eğer try blogunun içerisi çok fazla büyüdüyse ve tryın kapsadığı kod parçası ilk bakışta try ile beraber ele alınamıyorsa, kod parçacığını fonksiyon haline getirip fonksiyonu try içerisinden çağırmak daha uygun olacaktır.
                    Dirty                                                           Clean

                    try                                                            try
                    {                                                              {
                      //  
                      //                                                              saveThePlanet(); 
                      //                                                             
                      //                                                           }catch
                      //                                                           {

                    } catch(ArgumentOutOfRangeException)                             // do something
                    {                                                              }
                        // do something                                            
                    }

6. Classlar

Olabildiğince küçük..

Classlar da tasarlanırken aynı fonksiyonlar gibi olabildiğince küçük olmalıdır. Fonksiyon yazarken bu küçüklüğü satır sayısıyla ölçebilirken classlarda ise sorumluluklar ile ölçebiliriz. Bir class sorumluluğunun dışında işler yapan fonksiyonları barındırmamalıdır ve bu sorumluluklar da olabildiğince daha ufak alt sorumluluk başlıklarına ayrılmalıdır. 

Classların sorumluluk kısıtlarını yaparken en kolay kopya çekebileceğimiz yer ilk kısımlarda da bahsettiğim gibi, classın ismidir. Classınızı isimledirirken kısa, sade ve anlaşılır bir isim bulamıyorsanız classınızın içerisinde çok fazla sorumluluk ve ayrı tellerden çalan fonksiyonlar olabilir ya da class isminiz mantık olarak nesnesi üretilebilecek bir kavram değilse ve çok genel bir isim ise aynı şeyi söyleyebiliriz.

Bir kitapta okuduğum bir tanımda class sorumluluk kapsamı için şöyle bir cümle dikkatimi çekmişti.

Bir classın ne amaçla yazıldığını ve ne iş yaptığını “eğer, ve, veya, ama” kullanmadan 25 kelimede anlatabiliyor olmalısınız. 🙂

  • Class nesnesi tanımlarken kod okunurluğunu artırmak için aşağıdaki gibi bir tanımlama daha uygun olacaktır.
                       Dirty                                         Clean
                   Worker worker = new Worker();                     Worker worker = new Worker
                   worker.Name= "Sam";                               {  
                   worker.Surname="Brown";                              Name= "Sam",
                   worker.Age=21;                                       Surname="Brown",
                   worker.Title="Engineer";                             Age=21,
                                                                        Title="Engineer"
                                                                     };

7. Commentler

İyi yerleştirilmiş bir yorum satırı okuyucu için çok faydalı olabilecek iken kötü ve düşünülmeden yazılmış yorum satırları kodu bir çöplük haline getirebilir. Çünkü yorum satırlarının %90’ının dayandığı sebep bellidir.  Kötü kodu perdelemek. Kötü ve ne yaptığı belli olmayan fonksiyon ve kod parçacıklarını açıklamak için yorum satırı yazmaya yöneliriz. Bu da kod için oldukça tehlikeli bir durumdur. Neden yorum satırları kod açısından bu kadar sıkıntılıdır derseniz, yorum satırları genelde yalan söyler. Kod değişir ve gelişir ancak yorum satırları maintain edilmez. Yorum satırı yazmaya harcadığımız zamanı kodu temizlemeye harcarsak daha doğru bir yatırım yapmış oluruz 🙂 Yorum satırını da artık kodun yetersiz kaldığını düşündüğümüz durumlarda kullanmalıyız.

  •   Gereksiz yorum
      int i=1; //sets i 1
  •   Niyeti belli etmeye çalışan yorum
           Dirty                                                   Clean
     if(isActive==2) // be sure that is active           if(isActive == Status.IsActive)
  • Zombie kod, kullanılmayan kod parçacklarının yorum satırı haline alınıp kod içesinde tutulmasıdır ki diğer developerlar tarafından fazlaca kafa karışıklığına yol açar. Developerin kafasında yorum satırındaki kod neden vardı? , yanlışlıkla mı yoruma alındı da unutuldu?, kim yaptı?, niye yaptı?, ileride bu koda ihtiyaç olucak mı yoksa artık tamamen işlevsiz mi? gibi sorular oluşturarak kafa karışıklığı yaratır ve   okunurluğu azaltır.

8. Appendix

8.a Malfly variables

Yazılımla tanıştığım zamanlarda kod yazmaya başladığımda ilk yaptığım kod boyunca kullandığım ne kadar değişken varsa kodun başında tanımlamak ve sonrada gerek duydukça bunları kullanmaktı 🙂 . Ancak tüm yazı boyunca dediğimiz gibi, kodu okurken bir kitabı okuyormuş gibi yukarıdan aşağıya okuyup anlamlandırabilmeliyiz. Hiç kitabı okurken kitapta geçecek olan karakterlerin hepsinin ilk sayfada verildiğine tanıklık ettiniz mi? Kitapta karakterler ne zaman hikayeye giriş yaparsa o zaman adı geçmeye başlar. Biz de kod yazarken tanımlayacağımız değişkenleri fonksiyonun başında değil de ne zaman o değişkenin kullanımına ihtiyaç olduysa o zaman tanımlamalıyız.

Değişkenleri tanımlarken en kısa lifetime’a sahip olacak şekilde tanımlama yapmalıyız.

8.b Settingler

Kod yazarken hiç bir setting hard-coded olarak kodun içerisinde yer almamalı. Kodun içerisinde yer alan settingler için her bir setting değişikliği istendiğinde yeni bir geliştirme, deploy ve live’a çıkış anlamına gelir. Db’de tutulan settingler için ise istenen her değişiklik dbye atılan bir sorgu ile halledilebilir kod dışarıdan yönetilebilir olur.

You may also like...

5 Responses

  1. Downloads Movie dedi ki:

    Follow along with Robert “Uncle Bob” Martin and Justin Martin as they apply the principles learned in the Clean Code series to write an iPhone app in Swift.

  2. İsimsiz dedi ki:

    Güzel

  3. Ali dedi ki:

    Ellerinize saglik. Güzel yazı olmuş.

  4. Fatih dedi ki:

    Merhaba,
    Emeğinize sağlık güzel bir paylaşım olmuş.

    Validation lar ile ilgili duruma katılmakla birlikte; her kontrol sonrasında return yerine tüm validationların yapılıp tek bir return ile dönüş yapılması daha anlamlı olacaktır. 10 adet eksik alanı olan bir servis için hepsi için tek tek servise gelip eksik olduğunu görmekten ise tek seferde tüm eksikler görülmüş olur.

    İyi Çalışmalar Dilerim…

    • cagataykiziltan dedi ki:

      merhaba, evet haklısınız. Yazıdaki haliyle herbir error dönüşü düzeltmesinde bir sonrakini görebilecek. Error textler arka arkaya toplanıp tek seferde return edilirse userın işi kolaylaşabilir. Teşekkürler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir