Clean Code İpuçları
Tags: cleancode, programming, beginners
Published: 2022-08-13 14:03:00

Kod'larımızı daha okunabilir ve temiz hale getirmek için bir çok makaleden derlenmiş kolay kullanılabilir ve kısa ipuçları :)

## 1. Erken Dönüş(Return Early) Tasarım Modelini Kullanın:


```
function saveItem(item) {
  if (item != null) {
    console.log("Validating");

    if (item.isValid()) {
      console.log("Saving item");
      item.save();
    }
}
```
Yukarıdaki örnekte yanlış bir şey yok ancak iç içe if fadeleri kullanarak yuvalama yapmak yerine item değeri null ise veya valid değilse early return (erken dönüş) kullanarak  aşağıdaki gibi fonsiyondan çıkmasını sağlayabiliriz.

```
function saveItem(item) {
  if (item == null) return;

  console.log("Validating");
  if (!item.isValid) return;

  console.log("Saving item");
  item.save();
}
```

## 2. Fonksiyon Parametreleri İçin Object Destructuring (Nesne Yıkımı) Kullanın

Bir nesneyi parametre olarak alan ve yeni bir değer döndürmek için o nesne üzerinde bir tür işlem gerçekleştiren bir fonksiyonumuz olduğunu varsayalım. Nesne yok etmeyi(object destructuring) kullanmadan şöyle bir şey elde edebiliriz:

```
function getFullName(person) {
  const firstName = person.firstName;
  const lastName = person.lastName;
  return `${firstName} ${lastName}`;
}
```

Bu kullanım şekli gerçekten ihtiyacımız olmadığında da firstName ve lastName olmak üzere iki geçici referans oluşturur.


Bunu uygulamanın daha iyi bir yolu, nesne yıkımını( object destructuring) kullanmaktır. Bir satırda hem firstName hem de lastName değerlerini almak için person nesnesini yok(destruct) edebiliriz:

```
function getFullName(person) {
  const { firstName, lastName } = person;
  return `${firstname} ${lastName}`;
}
```
Ve parametreleri destruct ederek bu kodu daha zarif bir hala getirebiliriz.  :)

```
function getFullName(person) {
  const { firstName, lastName } = person;
  return `${firstname} ${lastName}`;
}
```

## 3. Pure (Saf) Fonksiyonları Kullanarak Yan Etkilerden (Side Effects) Kaçının:

Fonksiyon yazarken, o fonksiyonun dışındaki değişkenleri değiştirmekten kaçınmak en iyisidir.

```
let items = 5;
function changeNumber(number) {
  items = number + 3;
  return items;
}
changeNumber(5);
```

Bu fonksiyonu çağırdığımızda item değişkeninin değerini değiştirdiğimiz için bu kullanım istenmeyen durumlara yol açar.

Bunun yerine pure(saf) fonksiyon kullanarak fonksiyonu aşağıdaki gibi yeniden yazabiliriz.

```
function addThree(number) {
  return number + 3;
}
```
Harici değişkeni kaldırdığımız için fonksiyonun davranışı artık tamamen öngörülebilir hale geldi.


## 4. SRP (Tek Sorumluluk İlkesi)

Sadece bir şey yapan kısa fonksiyonlar yazın.
Bu kodun, iç içe yapıya sahip olmaması veya ikiden fazla girinti düzeyine sahip olmaması gerektiği anlamına gelir.

Yanlış kullanım:
```
function signUpAndValidate() {
}
```

Yerine:

```
function signUp() {
}
function validate() {
}
```

## 5. Anlamlı Değişken ve Fonksiyon Adları Kullanın:

** Fonksiyonlar eylemleri gerçekleştirir bu nedenle fonksiyonlarınızı adlandırırken filleri kullanın**

```
// bad
function passwordValidation() {
}
// good
function validatePassword() {
}
```

**Diziler için çoğul kullanın**

```
const animal = ["cat", "dog", "bird"];
const animals = ["cat", "dog", "bird"];
```

**Callback fonksiyonlarında yineleme yaparken anlamlı isimlendirmeler kullanın**

```
animals.forEach((a) => {
console.log(a);
});
// do this
animals.forEach((animal) => {
console.log(animal);
});
```


## 6. Kodunuzu yeniden kullanılabilir ve anlaşılır kılmak için benzer değişkenleri ve fonksiyonları gruplayın. 


## 7. DRY İlkesi:

Kendinizi tekrar etmeyin. Aynı kodu birden çok yerde kullanmanız gerekiyorsa onu bir fonksiyona dönüştürün.

## 8. Okunabilir Kod Oluşturmak İçin Boş Satırlar Kullanın

```
function saveItem(item) {
  if (item == null) return;
  console.log("Validating");
  if (!item.isValid) return;
  console.log("Saving item");
  item.save();
}
function Delete(item) {
  console.log("Delete item");
  item.delete();
}
```


```
function saveItem(item) {
  if (item == null) return;

  console.log("Validating");
  if (!item.isValid) return;

  console.log("Saving item");
  item.save();
}

function Delete(item) {
  console.log("Delete item");
  item.delete();
}
```

## 9. Birim(Unit) Testini kullanın ve Teste Dayalı Geliştirme(TDD-Test Driven Development) Uygulayın:

Unit testleri sayesinde kodda değişiklik yapmak ve hataları azaltmak daha kolay hale gelir.

Yazılım geliştirmede, gereksinimlerin belirli test senaryolarına dönüştürüldüğü ve ardından yazılımın yeni testleri geçecek şekilde geliştirildiği Test Odaklı Geliştirme (TDD) adı verilen bir süreç vardır.

☼ Tasarımı yap
☼ Testi yaz
☼ Geliştirmeyi yaz
☼ Testi yap

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tkms47btvzwhhj1nq1n.png)
 
TDD süreci aşağıdaki adımları içerir;

Belirtilen gereksinimlere göre yazılım geliştirici bir test senaryosu yazar
Bu testler gerçekleştirilir ve bir özelliğin geliştirilmesinden önce yazıldığı için başarısız olması beklenir
Geliştirme ekibi tarafından testin başarıyla geçmesi için kodlama yapılır
Bütün testlerin başarılı olması sağlanır
Kod tekrar gözden geçirilir ve düzenlenir. İyileştirme veya temizleme yapılır


## 10. Gereksiz Yorumlar Yazmaktan Kaçının
Kodunuzda gereksiz yorumlardan kaçınmak için değişkenler, işlevler veya dosyalar için anlamlı adlar kullanın.

_Bir yorum eklemek üzereyken kendinize şu soruyu sorun: "Bu yoruma gerek kalmayacak şekilde kodu nasıl iyileştirebilirim?" Kodu geliştirin ve ardından daha da net hale getirmek için belgeleyin._
**-Steve McConnell**


## 11. Refaktör

Bir kodu yeniden düzenlemek gerçekten iyi bir beceridir, neler olup bittiğinin farkında olmanızı sağlar ve yeniden düzenleme yaparken daha iyi hale gelir, bir süre sonra kodunuza geri dönmek ve geliştirmek her zaman iyi bir uygulamadır.


## 12. Tüm Değişken Bildirimlerinizi Bir Arada Tutun:

Projeleriniz büyümeye başladığında, sınıflarınızın muhtemelen birçok değişkeni olacaktır. İlk olarak, tüm değişken bildirimlerinizi sayfanın en üstünde veya en azından bir yerde bir arada tutmalısınız - bu, her türlü aramayı hızlandırır.


## 13. Doğru Mimariyi Seçin
Projelerinizi oluşturmak için kullanabileceğiniz birçok paradigma ve mimari vardır. Bu ipucunun, en iyisini seçmekle ilgili değil, ihtiyaçlarınız için doğru olanı seçmekle ilgili olduğuna dikkat edin.

_"Gereksinimler ve tasarım olmadan programlama, boş bir metin dosyasına hata ekleme sanatıdır."_
_Louis Srygley_

Örneğin, Model-View-Controller (MVC) modeli, web geliştirmede popülerdir çünkü kodunuzu düzenli tutmaya yardımcı olur ve bakım çabalarını en aza indirecek şekilde tasarlanır.


## 14. Sihirli Sayı:

Sihirli bir sayı, net bir anlamı olmayan bir sayı atadığımız anlamına gelir. Bazen belirli bir amaç için bir değer kullanırız ve değeri anlamlı bir değişkene atamayız. Bu durum kodunuzu okuyan kişinin bu sayının amacını anlamamasına neden olur.

```

//Bad practice
for(let i = 0; i < 50; i++){
    //do something
}
//Good practice
let NUMBER_OF_STUDENTS= 50
for(let i = 0; i < NUMBER_OF_STUDENTS; i++){
    //do something
}
```

## 15. Tasarım Kalıplarını Kullanın

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgz37r5owrow6brdeqng.png)
 

**SOLID Tasarım İlkeleri**

**Single Responsibility Principle (Tek Sorumluluk İlkesi):** Bir sınıfın yalnızca bir işi olmalıdır

**Open Closed Principle (Açık Kapalı İlkesi):** Bir sınıf genişletmeye açık ancak değişikliğe kapalı olmalıdır.

**Liskov Substitution Principle (Liskov Değiştirme İlkesi):** Bir programdaki nesneler, programın doğruluğunu değiştirmeden alt türlerinin örnekleriyle değiştirilebilir olmalıdır.

**Interface Segregation Principle (Arayüz Ayrıştırma İlkesi):** Bir istemci asla kullanmadığı bir arayüzü uygulamaya zorlanmamalıdır.

**Dependency Inversion Principle (Bağımlılık Tersine Çevirme Prensibi):** Yüksek seviyeli modül, düşük seviyeli detaya değil, yüksek seviyeli genellemeye dayanmalıdır.

**Diğer Tasarım Kalıpları**

**Composing Objects Principle (Nesneleri Oluşturma İlkesi):** Sınıflar, kalıtım(inheritance) yerine toplama yoluyla kodun yeniden kullanımını sağlamalıdır.

**Demeter Yasası / Principle of Least Knowledge(En Az Bilgi Prensibi):** Sınıflar mümkün olduğunca az sayıda diğer sınıfı bilmeli ve bunlarla arayüz oluşturmalıdır.

**Abstraction (Soyutlama):** Yalnızca ilgili bilgileri göstererek basitleştirin

**Encapsulation (Kapsülleme):** Nitelikleri ve davranışları bir nesnede gruplama ve gerektiğinde özellikleri açığa çıkarma.
Bir grup kod sıklıkla birlikte kullanılıyorsa, kapsüllmeyi kullanın.

**Decomposition (Ayrıştırma):** Bir varlığı ayrı ayrı uygulanabilecek parçalara ayırma
Bir sınıf çok büyükse ayrıştırma(decomposition) kullanın.

**Generalization (Genelleme):** Başka yerlerde yeniden kullanılabilecek sınıfların ortak özelliklerini çarpanlarına ayırma.
Aynı kod, küçük değişikliklerle birlikte, kod tabanının birden çok bölümünde kullanılıyorsa, genellemeyi kullanın.

**Coupling and Cohesion:** Gevşek bağlı modüller daha az bağımlıdır ve yeniden kullanımı daha kolaydır, yüksek uyum ise net bir amacı olan ve olması gerekenden daha karmaşık olmayan bir modülü tanımlar.
Bir yerdeki değişiklik diğer birçok parçada değişikliğe neden oluyorsa, bu sıkı bağlantı anlamına gelir.

**Inheritance (Kalıtım):** Alt sınıfların bir üst sınıftan miras aldığı veya bir arabirim aracılığıyla uygulayan nitelik veya davranışlar.

**Information Hiding(Bilgi Gizleme):** Modüller yalnızca yapması gereken bilgilere erişebilmelidir.

**Information Hiding (Endişelerin Ayrımı):** Farklı modüllerde farklı endişeler olmalıdır

**KISS principle:** KISS ilkesi, çoğu sistemin karmaşık hale getirilmek yerine basit tutulursa en iyi şekilde çalıştığını belirtir; bu nedenle tasarımda basitlik temel hedef olmalı ve gereksiz karmaşıklıktan kaçınılmalıdır.


## 16. Sandi Metz’s Kuralları

Class'lar da 100 satırdan fazla kod olamaz
Methodlar ve fonksiyonlarda 5 satırdan fazla kod olamaz
Bir method'a 
en fazla 4 parametre iletin
Controller'lar yalnızca bir nesneyi başlatabilir


_"Bir geliştirici olarak, yalnızca bir şeyleri teslim etme konusunda endişelenmememiz gerektiğini unutmayın. Bundan daha fazlasıdır; bu, kodu desteklemesi gereken bir sonraki geliştiriciyi düşünmekle ilgilidir. Bu yüzden lütfen bir sonraki projenizde bulmak istediğiniz kodunuzu okunaklı bir şekilde bırakın."_

Resources :)
Many thanks to
☼ [Dominic Duke](https://domtech.hashnode.dev/5-tips-for-writing-cleaner-code)
☼ [Lauren Alexander](https://www.myhatchpad.com/insight/7-practical-tips-for-writing-clean-code/)
☼ [Claudia Sanjuan]( https://blog.unosquare.com/10-tips-for-writing-cleaner-code-in-any-programming-language)
☼ Steve McConnell
☼ [Ahmet Cokgungordu](https://acokgungordu.medium.com/yaz%C4%B1l%C4%B1m-geli%C5%9Ftirme-s%C3%BCrecinde-test-tdd-atdd-ve-bdd-aras%C4%B1ndaki-farklar-8332c20aaec7#:~:text=TDD%20s%C3%BCreci%20a%C5%9Fa%C4%9F%C4%B1daki%20ad%C4%B1mlar%C4%B1%20i%C3%A7erir,ba%C5%9Far%C4%B1yla%20ge%C3%A7mesi%20i%C3%A7in%20kodlama%20yap%C4%B1l%C4%B1r)
☼ [Awedis Keofteian](https://dev.to/awedis/10-tips-to-write-clean-code-22cj) 
☼ [Amal Hasni](https://towardsdatascience.com/8-tips-to-write-cleaner-code-376f7232652c)
☼ [Kay Jan Wong](https://towardsdatascience.com/3-tips-for-writing-clean-codes-beyond-coding-best-practices-c53b04120c3)
☼ [Joel Lee](https://www.makeuseof.com/tag/10-tips-writing-cleaner-better-code/)
☼ [Shoaib Mehedi](https://betterprogramming.pub/12-conventions-for-writing-clean-code-e16c51e3939a)
and
☼ https://www.geeksforgeeks.org/7-tips-to-write-clean-and-better-code-in-2020/
☼ https://www.pluralsight.com/blog/software-development/10-steps-to-clean-code?clickid=SKFQgUxRexyNT4OXXR3ok2jQUkDyfpWv5QPMyQ0&irgwc=1&mpid=29332&aid=7010a000001xAKZAA2&utm_medium=digital_affiliate&utm_campaign=29332&utm_source=impactradius
☼ https://en.wikipedia.org/wiki/SOLID
☼ https://en.wikipedia.org/wiki/KISS_principle