Temiz kod yazmak kolay bir iş değildir. Farklı ipuçları ve uygulamalarla deney yapmayı gerektirir. Maalesef, bu konuda çok fazla fikir var. Yazılımcılar bu fikirler arasında kaybolup gidebilir. Bu karmaşayı çözmek için yazımızda önce temiz kod yazmanın bazı faydalarını değineceğiz. Ardından, ipucu ve yöntemlere göz atacağız.

Temiz kod yazmanın faydaları

Temiz kodun bize sağladığı bazı faydalara göz atarak başlayalım.

Ana faydalarından biri, kodu anlamaya çalışmak için harcadığımız zamanı en aza indirgemesidir. Karışık kod ise herhangi bir geliştiriciyi yavaşlatma ve işini çok daha zor hale getirme konusunda olağanüstü bir yeteneğe sahiptir. Kod ne kadar karmaşıksa, kodu anlamak için geçirilen zaman o kadar artar. Hatta kod çok fazla karmaşıksa yazılımcı projeyi yeniden oluşturup yazmaya karar verir. Bu tür çok karmaşık kodlara spagetti kod denir.

1. Başlaması ve devam etmesi kolay

Bunu basit bir örnekle göstermeme izin verin. Diyelim ki çok uzun bir aradan sonra projelerimizden birine döndünüz. Belki önceki müşterilerimizden biri bizimle iletişime geçti ve aynı projede bize başka bir iş teklifi sundu. Şimdi, gelen projede kolaya kaçarak yazdığımız o karmaşık kodu çözme zamanı.

Önce kendimiz için yazalım.

Sonuç olarak, şimdi projeye gerekenden çok daha fazla zaman harcamalıyız. Çünkü daha önce yazdığımız kodu anlamamız gerekiyor. En başından itibaren temiz kodlama yaparak bu dertten kurtulmuş oluyoruz. Yazdığımız kodun çok çok dağınık olduğunu varsayarsak projeye yeniden başlama ihtimalimizde var. Bu durum müşterimizi memnun etmeyecektir ve bize hocam bu kodu zaten sen yazmadın mı diyecektir.

Diğer yandan yukarıda verdiğim örneğin tam tersini düşünelim. Tertemiz bir kod yazdık ve iş tekrardan bize geldi. Kodu anlamamız çok kısa sürdü ve gereken geliştirmeleri yaptık. Karmaşık kodu anlamaktan artan zaman size kalacaktır. Bir kahve alıp dizinizi izleyebilirsiniz.

Unutmayın ki temiz kodlama tek bizi etkileyen bir şey değildir. Birden fazla geliştiricisi olan projelerde diğer yazılımcıların işini kolaylaştırıp sizin hakkınızda iyi şeyler düşünmelerini sağlayın. Aslan yattığı yerden belli olur ata sözünü aklınıza getirin ve kaliteye odaklanın.

Yapılan herşey eylemi gerçekleştireni yansıtır. Nasıl anılmak istersiniz?

2. Ekipler için daha iyi

Temiz kod yazmanın bir başka avantajı kodu daha hızlı benimsemeye izin vermesidir. Başka bir geliştirici ile çalımanız gerektiğini düşünelim. Kodu anlaması ve onunla nasıl çalışacağını öğrenmesi ne kadar sürer? Değişken bir durum. Kodumuz dağınıksa ve kötü yazılmışsa, çözmek için daha fazla zamana ihtiyacı olacaktır. Diğer yandan, kodumuz temiz, okunabilir, anlaşılır ve basitse, daha hızlı adapte olacaktır.

Çaba gösterdiğimizde ve temiz kod yazdığımızda, diğer insanların onu örnek alması, çalışması daha kolay olacaktır. Elbette, her yeni geliştiricinin kodunuzu öğrenmesine ve anlamasına yardımcı olmak için biraz zaman ayırmanız gerekecektir. Haftalar değil sadece birkaç günden bahsediyoruz. Ayrıca temiz kod, ekibe daha fazla yazılımcı getirmemize ve hepsinin kodumuzu aynı anda anlamalarına yardımcı olur. Basitçe ifade etmek gerekirse, kod ne kadar temiz olursa, onu açıklamak o kadar kolay olur ve yanlış anlaşılmalar o kadar az olur.

3. Takip etmesi daha kolay

Bir yazılımcının yazılımlarımızı takip edebildiğinden ve buna istekli olduğundan emin olmamız gerekir. Yine, karışık koddan ziyade temiz kodla bunu başarmak daha kolay olacaktır.

Geliştiricilerimizden biri mevcut kod yapısını kullanmamaya karar verirse? Bu sorun genellikle kendi kendine çözülür. Diyelim ki aynı yapı üzerinde çalışan yazılımcılarımız var ve bir tanesi oluşturduğumuz şablondan sapmaya başlıyor.

  1. Diğer geliştiriceler temiz bir şeyin karmaşık bir hale gelmemesi için uyarıda bulunacaktır.
  2. Bu ısrarcı tutumuna devam edip işten atılacaktır. :)

Diğer bir örnek; geliştiricinin ekibin geri kalanını kendi kurduğu bir yapıyı benimsemeye ve takip etmeye gerçekten ikna etmesidir. Geliştirici tarafından önerilen yapı daha temizse ve daha iyi sonuçlar veriyorsa bu iyi bir şey olabilir. Kodumuzu yazmak ve temiz tutmak, onu geliştirmek için her türlü fırsatı görmezden gelmemiz gerektiği anlamına gelmez. Aksine, her zaman mevcut uygulamalarımızı sorgulamamız ve iyileştirme için bu fırsatları değerlendirmemiz gerekir.

Temiz kodlama için ipuçları

Şimdi, temiz kod yazmanın faydalarını anlatıık, bunu yapmamıza yardımcı olacak bazı ipuçlarını öğrenmenin zamanı geldi. Yazının ilerleyen kısımlarında göreceğimiz gibi temiz kodun benimsediği bazı kurallar vardır. Bu kurallar, kodumuzu daha temiz, okunabilir, daha anlaşılır ve daha basit yapan şeylerdir. Tüm bu kuralları hayata geçirmek herzaman gerekli değildir. Sadece birkaçını kullanmamızın bile çok önemli faydaları olabilir.

1. Kodu insanlar için okunabilir hale getirin

Yazdığımız kodun makineler tarafından yorumlanacağı doğrudur. Ancak bu, okunabilirliğini ve anlaşılırlığını ihmal etmemiz gerektiği anlamına gelmez. Her zaman başka bir insanın kodumuza ulaşma veya onunla çalışmak zorunda kalma ihtimali vardır. Başkalarının asla görmeyeceği bir kod yazsak bile kodumuzu okumayı kolaylaştıracak şekilde yazmak kendi iyiliğimizedir. Nasıl?

En kolay yol boşluk kullanmaktır. Göndermeden önce kodumuzu küçültmemizde bir sakınca yoktur. Ancak, küçültülmüş gibi görünen bir kod yazmak gerekli değildir. Bunun yerine, kodumuzun yapısını daha okunaklı hale getirmek için girinti, satır sonu ve boş satırlar kullanabiliriz. Bu uygulamayı benimsemeye karar verdiğimizde, kodumuzun okunabilirliği ve anlaşılabilirliği önemli ölçüde artabilir. O halde kodumuza bir kez bakmak onu anlamak için yeterli olabilir. İki basit örneğe bir göz atalım.

Kod:

// Kötü
const userData=[{userId: 1, userName: 'Anthony Johnson', memberSince: '08-01-2017', fluentIn: [ 'English', 'Greek', 'Russian']},{userId: 2, userName: 'Alice Stevens', memberSince: '02-11-2016', fluentIn: [ 'English', 'French', 'German']},{userId: 3, userName: 'Bradley Stark', memberSince: '29-08-2013', fluentIn: [ 'Czech', 'English', 'Polish']},{userId: 4, userName: 'Hirohiro Matumoto', memberSince: '08-05-2015', fluentIn: [ 'Chinese', 'English', 'German', 'Japanese']}];

// Daha iyi
const userData = [
  {
    userId: 1,
    userName: 'Anthony Johnson',
    memberSince: '08-01-2017',
    fluentIn: [
      'English',
      'Greek',
      'Russian'
    ]
  }, {
    userId: 2,
    userName: 'Alice Stevens',
    memberSince: '02-11-2016',
    fluentIn: [
      'English',
      'French',
      'German'
    ]
  }, {
    userId: 3,
    userName: 'Bradley Stark',
    memberSince: '29-08-2013',
    fluentIn: [
      'Czech',
      'English',
      'Polish'
    ]
  }, {
    userId: 4,
    userName: 'Hirohiro Matumoto',
    memberSince: '08-05-2015',
    fluentIn: [
      'Chinese',
      'English',
      'German',
      'Japanese'
    ]
  }
];

Kod:

// Kötü
class CarouselLeftArrow extends Component{render(){return ( <a href="#" className="carousel__arrow carousel__arrow--left" onClick={this.props.onClick}> <span className="fa fa-2x fa-angle-left"/> </a> );}};

// Daha iyi
class CarouselLeftArrow extends Component {
  render() {
    return (
      <a
        href="#"
        className="carousel__arrow carousel__arrow--left"
        onClick={this.props.onClick}
      >
        <span className="fa fa-2x fa-angle-left" />
      </a>
    );
  }
};

2. Değişkenler, işlevler ve yöntemler için anlamlı isimler kullanın

Anlaşılır ve temiz kod yazmamıza yardımcı olacak ikinci ipucuna bir göz atalım. Bu ipucu değişkenler, işlevler ve yöntem için anlamlı isimler kullanmakla ilgilidir. Anlamlı ne anlama geliyor? Anlamlı isimler, değişkenin, işlevin veya yöntemin amacını sadece bizim değil, başkalarının da anlayabileceği kadar açıklayıcı isimlerdir. Başka bir deyişle, adın kendisi değişkenin, işlevin veya yöntemin ne için kullanıldığını veya ne içerdiğini anımsatmalıdır.

Kod:

// Kötü
const fnm = ‘Tom’;
const lnm = ‘Hanks’
const x = 31;
const l = lstnm.length;
const boo = false;
const curr = true;
const sfn = ‘Remember the name’;
const dbl = [‘1984’, ‘1987’, ‘1989’, ‘1991’].map((i) => {
  return i * 2;
});

// Daha iyi
const firstName = ‘Tom’;
const lastName = ‘Hanks’
const age = 31;
const lastNameLength = lastName.length;
const isComplete = false;
const isCurrentlyActive = true;
const songFileName = ‘Remember the name’;
const yearsDoubled = [‘1984’, ‘1987’, ‘1989’, ‘1991’].map((year) => {
  return year * 2;
});

Ancak akılda tutmamız gereken bir şey var. Açıklayıcı adlar kullanmak, istediğimiz kadar çok karakter kullanmakta özgür olduğumuz anlamına gelmez. İyi bir kural, isimleri üç veya dört kelimeyle sınırlamaktır. Dörtten fazla kelime kullanmamız gerekiyorsa, belki de aynı anda çok fazla şey yapmaya çalışıyoruz anlamına gelebilir ve bu durumu kodumuzu bölerek yapabiliriz. Bundan dolayı, gerektiği kadar karakter kullanmalıyız.

3. Bir fonksiyonun veya yöntemin yalnızca bir görevi gerçekleştirmesine izin verin

Kodlamaya başladığımda, isviçre çakısı gibi fonksiyonlar yazardım. Yazdığım tek bir fonksiyon onlarca işi hallederdi ve bununla böbürlenirdim. Benden başka neredeyse hiç kimse fonksiyonun ne yaptığını ve nasıl kullanılacağını bilmiyor olması. Hatta bazen ben bile çözmekte sorun yaşardım.

Sonra birisi bu harika tavsiyeyi verdi. Her işlevin veya yöntemin yalnızca bir görevi gerçekleştirmesi tavsiyesi. Bu basit tavsiye her şeyi değiştirdi ve en azından eskisinden daha temiz kod yazmama yardımcı oldu. O andan itibaren, diğer insanlar yazdığım kodu anlayabildiler. Ya da daha önce ihtiyaç duydukları kadar zamana ihtiyaçları yoktu.

Fonksiyonlarınız için açıklayıcı adlar bulmakta güçlük çekiyorsanız veya başkalarının kullanabilmesi için uzun talimatlar yazmanız gerekiyorsa, bu ipucunu düşünün. Her fonksiyonun yalnızca bir görevi gerçekleştirmesine izin verin.

Her işlevin veya yöntemin yalnızca tek bir görevi gerçekleştirmesine izin verme uygulamasına Single Responsibility Principle (Tek Sorumluluk Prensibi) denir. Bu kodlama prensibi, Robert C. Martin tarafından SOLID olarak da bilinen 5 nesne yönelimli tasarım ilkesinden biri olarak tanıtıldı. Daha fazlasını öğrenmek istiyorsanız bu makaleyi okumaya devam etmenizi öneririm.

Kod:

// Example no.1: Simple subtraction
function subtract(x, y) {
    return x - y;
}

// Example no.2: Simple multiplication
function multiply(x, y) {
    return x * y;
}

// Example no.3: Double numbers in an array
function doubleArray(array) {
  return array.map(number => number * 2)
}

4. Açıklama için yorumları kullanın

Değişkenlerimiz, işlevlerimiz ve yöntemlerimiz için anlamlı isimler bulmaya ne kadar uğraştığımızın önemi yok. Kodumuz kendi başına hala olabileceği kadar temiz ve anlaşılır değil. Hala daha fazla açıklama gerektiren bazı satırlar var. Fonksiyona baktığımızda kafamızı karıştıran, anlamadığımız noktolar olabilir. Sizde içinizden şunu geçirmişsinizdir.

Bunu neden yazmışım.

Bazen bir sorunu çözmek için alışılmadık bir yaklaşım kullanmak zorunda kalabiliriz çünkü başkabir yöntem işe yaramıyor veya daha iyi bir çözüm bulmak için yeterli zamanımız bulunmayabilir. Bunu kodun kendisiyle açıklamak zor olabilir. Kodumuz içerisinde yorum kullanmak, bu sorunu çözmemize yardımcı olabilir. Yorumlar, diğer insanlara neden yazdığımızı ve neden bu şekilde yazdığımızı açıklamamıza yardımcı olabilir. Sonuç olarak, diğer insanların kdoumuzu anlamak için beyin fırtanısı yapmasına gerek kalmadan yorumları kodumuza eklememiz faydalı olacaktır.

Dahası, nedenlerimizi açıkladığımızda, diğer insanlar sorunu çözmenin ve kodu geliştirmenin daha iyi bir yolunu bulabilir. Bu ancak sorunun ne olduğunu ve istenenilen şeyin ne olduğunu bildiklerinden dolayı işe yarayacaktır. Başkalarının bu bilgileri bilmeden daha iyi bir çözüm üretmesi çok daha zor olacaktır.

Bu yüzden yazdığımız kodun bir bakışta anlaşılamayacak seviyede olduğunu düşündüğümüzde yorumumuzu yazalım. İnsanları tahmin etmeye zorlamaktansa, açıklayıcı bir yorum daha olur.

Bununla birlikte, yalnızca gerekli olduğunda yorumları kullanmalıyız. Sonsuz yorum satırları yazmak, kötü yazılmış bir kodu temize geçmemize yardımcı olmayacaktır. Kod kötüyse, nasıl kullanılacağına dair talimatlar ekleyerek değil, kodu düzelterek sorunu çözmeliyiz.

5. Tutarlı olun

Bize yazım stilini bulduğumuzda, ona bağlı kalmalı ve her yerde kullanmalıyız. Farklı projelerde farklı yazım stillerini kullanmak bence mantıklı değil. Çünkü her çalıştığınız projede farkılı stiller kullanmak sizinde işinizi zorlaştıracaktır. Geri dönülen projede kullandığımız kodlama stilini yorumlamak zamanımızı alacaktır.

Yapılacak en iyi şey, bir kodlama stili seçmek ve ardından tüm projelerimizde bu prensibe bağlı kalmaktır. Daha sonra eski kodumuza dönüp kaldığımız yerden devam etmek veya onu iyileştirmek çok daha kolay olacaktır. Peki yeni denemeler ne olacak? Yeni kodlama stillerini denemek iyi bir şeydir. İşimizi yapmanın daha iyi yollarını bulmamıza yardımcı olabilir. Ancak, ana projelerimiz değil, ayrı deneysel projeler veya alıştırmalar üzerinde farklı uygulamaları denemek daha iyidir.

Ayrıca, bir deney yapmaya karar verdiğimizde, bu uygulamayı birçok kez ve birden çok örnek üzerinde denemeliyiz. Bu deneyi pekiştirmek ve işe yaradığını görmek için zaman ayırmalıyız. Ne zamanki "işte bu" dedik onu uygulamaya başlayabiliriz.

6. Kodunuzu belli periyotlarla inceleyin

Temiz kod yazma konusunda son ipucumuz. Basitçe temiz kod yazmak her şey değildir. Noktalı virgül koyup işim bitti demek yok. Bir sonraki adım, kodumuzu temiz tutmaktır. Temiz kod, bakım gerektirir. Bir şeyi yazdığımızda, düzenli olarak gözden geçirmeli, temizlemeli ve geliştirmeye çalışmalıyız. Aksi takdirde, eski kodumuzu gözden geçirmez ve güncellemezsek, yakında güncelliğini yitirecektir. Tıpkı cihazlarımızda olduğu gibi. Onları en iyi durumda tutmak istiyorsak düzenli olarak güncellememiz gerekir.

Kendimizi sürekli güncelliyorsak, kodumuzuda güncellemeliyiz.

Sonuç olarak, yazımı en az seviyede teknik terim kullanarak yeni başlayanlara rehber olması için yazmaya çalıştım. Bu yazıda yazılanlar best practice (en iyi çözüm) değil. Ama bunları uygulamaya başladığınızda en azından iyi bir başlangıç yapmış olursunuz.

Zaman ayırıp okuduğunuz için teşekkür ederim.