İçeriğe geç →

JavaScript için Temiz ve Okunabilir Kod Yazmak

Temiz ve okunabilir kod… Yeşillikler arasında yürümek, en sevdiğiniz kahvenin kokusunu içinize çekmek ya da pofuduk bir tavşan gibi bir şeydir…

Yazılım geliştirme konusunda tecrübe kazanmış her kişi az çok anlamıştır ki; kodlarımızı makineler için değil gelecekteki kendimiz ve diğer geliştiriciler için yazıyoruz. Sadece çalışan ve işini yapan fakat okuması zor, kötü kod yazmak, o anı kurtarsa da, uzay-zaman içinde bilinmeyen bir yerde, yeni bir serseri tohum oluşması demektir. Bu tohumlar zamanları gelene kadar kendi aralarında eğlenip durur ve bazen birkaçı birleşip daha büyük tohum haline gelir. Görseniz onun tohum değil aslında bal kabağı ya da karpuz olduğunu söylersiniz. Vakit geldiğinde de bir kara deliğin içine girip, kurbanlarının beyninin içinde beliriverirler. Hayat enerjisini sömürürler ve karamsarlık, mutsuzluk, küfür etme isteği enzimleri salarlar.

Bilim bu tohumlar konusunda çaresizdir ve yapabileceği tek şey, bu tohumların rastgele geliştiriciler yerine o tohumun oluşmasına kim sebep olduysa onun beyninde çıkması için dua etmektir.

Halbuki temiz ve okunabilir kod yazmak o kadar da zor değildir. Bunun için size yardımcı olacak araçlar var ama bu yazının konusu değiller. O yüzden ufak bir referans listesi verip geçiyorum;

Javascript yazarken edindiğim tecrübeler ve okuduğum kaynaklardan öğrendiklerimle, birkaç ufak ama etkili olduğuna inandığım bazı “best practice”leri paylaşmak istiyorum.

# Tip Kontrolü

== yerine === tercih et. Minik bir şey gibi görünse de, kod mantığını tamamen etkileyebilir. Ortamlarda “strong type checking” diye de bahsedilir.

0 == false // true
0 === false // false

const value = "1";
if (value === 1) {
  // bu kısım çalışmayacak
  console.log(value);
}

# Değişkenlerin ve Fonksiyonların İsimlendirilmesi

“Her mesleğin bir zorluğu vardır” derler. Yazılım geliştirirken bazen değişkenlere, fonksiyonlara vs… isim vermek zor olabilir. Ne kadar zor olsa da önemli olan değişkenlere isim verirken, o değişkenin amacını anlatan iyi bir isim vermektir. Uzun ya da kısa olması pek de önemli değil. Başka birisi ya da gelecekteki siz, bir değişkeni gördüğünüz zaman ne yaptığını anlayabilmeniz gerek.

// Kötü Örnek
let mlvl = 10;
let y = getSomething(lv);

let allow;
if (user.level > 30) {
  allow = true;
}

// İyi Örnek
const MIN_LEVEL = 10;
const userLevelGreaterThanMinLevel = user.level > MIN_LEVEL;
// const isUserLevelValid = user.level > MIN_LEVEL;
// Kötü
const items = ["Foo", "Bar", "Baz", "Qux"];
items.forEach(i => {
  runSomething();
  anotherFunc();
  anotherAnotherFunc();
  // ...
  // ...
  // Bu noktada i değişkeninin anlamsız gelmesi mümkün
  runSomethingElse(i);
});

// İyi
items.forEach(i => {
  runSomething();
  anotherFunc();
  anotherAnotherFunc();
  // ...
  // ...
  // Böyle hayat daha güzel
  runSomethingElse(item);
});

Gereksiz yere değişkenlerin isimlerini uzatmaya gerek yok;

// Kötü
const product = {
  productName: "Flying Fish",
  productCode: "Penguin-X",
  productColor: "Gray"
};

product.productName;

// İyi
const product = {
  name: "Flying Fish",
  node: "Penguin-X",
  color: "Gray"
};

product.name;

Değişkenlerdeki mantığı fonksiyonları isimlendirirken de kullanmamız gerek. Fonksiyonun işlevini açıklayan isimler seçmeye özen göstermek gerek.

// Kötü
function noti(email) {
  // kodlar
}

// İyi
function notifyUser(email) {
  // kodlar
}

Bazıları da der ki; “Bir fonksiyon çok fazla parametre almamalı. İki ya da daha az iyidir. Hem test etmesi kolay olur.”

// Kötü
function getProducts(code, description, fromDate, toDate) {
  // kodlar
}
getProducts('foo', 'lorem ipsum', '2019-10-10', '2019-10-12');

// İyi
function getProducts({ code, description, fromDate, toDate }) {
  // kodlar
}
getProducts({ code: 'foo', description: 'lorem ipsum', fromDate: '2019-10-10', toDate: '2019-10-12' });

Fonksiyonlar içinde parametrelerin varsayılan değerlerini, koşul ifadeleri kullanarak kontrol etmek yerine, parametrelere varsayılan değer vermek daha iyidir.

// Kötü
function createMonster(type) {
  const monsterType = type || "earth";
  // kodlar
}

// iyi
function createMonster(type = "earth") {
  // kodlar
}

# Global Objeler ve ES Sınıfları

Buna pek ihtiyacım olmadı ama aklımda bulunması açısından buraya not düşmek iyi olur. Var olan global objelere ekstra işlevler katmak istersek, ES ‘in sunduğu sınıfları kullanmak daha iyi bir yöntem olacaktır.

// Kötü
Array.prototype.mySuperFunc = function superFunc() {
  // kodlar
};

// İyi
class MySuperArray extends Array {
  mySuperFunc() {
    // kodlar
  }
}

ES sınıflarını sadece global objeleri genişletmek için değil, prototype üzerinden fonksiyonlar ile sınıflar oluşturmak yerine de kullanmak, artık daha iyi ve kolay olacaktır.

// Kötü
const Person = function(name) {
  if (!(this instanceof Person)) {
    throw new Error("Instantiate Person with `new` keyword");
  }

  this.name = name;
};

Person.prototype.sayHello = function sayHello() { /**/ };

const Student = function(name, school) {
  if (!(this instanceof Student)) {
    throw new Error("Instantiate Student with `new` keyword");
  }

  Person.call(this, name);
  this.school = school;
};

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.printSchoolName = function printSchoolName() { /**/ };

// İyi
class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    /* ... */
  }
}

class Student extends Person {
  constructor(name, school) {
    super(name);
    this.school = school;
  }

  printSchoolName() {
    /* ... */
  }
}

# Kod Tekrarı ve Gereksiz Kodların Temizlenmesi

Temiz ve okunabilir kod yazmanın temellerinden birisi kod tekrarından kaçınmaktır. Aynı işleri yapan kodları tekrar tekrar yazmak yerine, fonksiyonlar haline getirmeye çalışmak daha iyi olacaktır.


Ayrıca artık kullanılmayan ölü kodları da mümkün olduğunca çabuk ve düzenli bir şekilde temizlemek gerek çünkü bir süre sonra o kodların ne işe yaradığını kimse hatırlamayacak ve gereksiz kalabalık oluşturmaktan başka işe yaramayacaklar.

Kategori: JavaScript

Yorumlar

Siz de düşüncelerinizi paylaşın

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back To Top