13 Mayıs 2018 Pazar

Code Simplicity ( Kod Basitliği - 5)

     S.a. Arkadaşlar,
     Kod basitliği kitabının 5.yazısına başlıyoruz bugün. Bildiğiniz üzere 9 yazılık  bir seri olacaktı. Bu yazıyla yolun yarısını da geçmiş oluyoruz. Seriyi de tamamlarız inşaallah en yakın zamanda. Geçen yazımızda yazılımın geleceği konusunu işlemiştik. Bugün ise yazılımdaki değişiklikleri işleyeceğiz. Kısa bir giriş yaptığımıza göre artık başlayabiliriz.
      Geleceğin önemini de anladığımıza göre bilmediğimiz yeni şeylere bakabiliriz. Güzel, öyleyse yazılımın zamanla değişmesine geçebiliriz. Bunun anlamı yazılımın da değişikliklere uyum sağlaması gerekir. Değişikliğin kuralını verecek olursak :

       "Yazılımın ömrü artıkça zamanla değişme ihtimali de artar."

        Yazılımın ömrü uzadıkça değişiklik yapma ihtimali de öyle artar. Hatta %100e  çıkabilir. 5 dakika sonra yazılımınız değişime ihtiyaç duymayabilir, ama 1 yıl sonra artık ufak değişiklikler yapmaya başlarsınız. 10 yıllar sonra ciddi değişiklikler olur. Tabi bu değişikliklerin nedenini bilmek zordur. Belki 4 tekerlikli araçlar için yazılım yapıyorsunuz ama ileride 18 tekerlikli araçlar da çıkabilir veya lise için bir yazılım yapıyorsunuzdur fakat lisedeki eğitim o kadar kötü olacak ki öğrencilere hiç bir faydası olmayacak. Bu örnekler çoğaltılabilir. Bu nedenle de değişim vazgeçilmez oluyor. Burada dikkat edilmesi gereken yer ise değişikliği tahmin etmek yerine sadece ihtiyaç duyduğun geliştirmeler yapmak gerekir. Mümkün olduğunca yazılımı esnek tasarlama ilerideki değişikliklere uyum sağlaması açısından önemlidir.

      Gerçek dünyadan bir yazılım örneği alınmış. Zamanla değişimin nasıl kaçınılmaz olduğunu anlatılmış. Yukarıdaki söylenenleri kanıtlama mahiyetinde olmuş bunu da böylece kısaca açıklamış olalım istedim.

     Üç Kusur
     Yazılım tasarımı yaparken en sık rastlanan 3 hatayı inceleyeceğiz sırasıyla
  1. İhtiyaç olunmayan kodu yazmak
  2. Değişiklik için kodu basitleştirmemek
  3. Çok genel olma

      İhtiyaç olunmayan kodu yazmak:  Bu aralar yaygın olan ve sizin de duymuş olduğunuz bir kural var: YAGNI. Temel olarak ihtiyaç duymadığın kodu yazmama üzerinedir. Bu doğru bir kuraldır , fakat yanlış isimlendirilmiştir. Gerçekten de kodu değiştirmeye ihtiyaç duyabiliriz, ama bunu nasıl olacağını önceden tahmin edemezsin. Eğer ihtiyacınız olmayan kodu yazarsanız daha sonra yapınızı tekrardan tasarlamak zorunda kalacaksınız. Kendinizi bu zaman tasarrufundan kurtarmak istiyorsanız en başından sadece ihtiyacınız olanı yazmanız gerekmektedir.

     İhtiyacınız olmayan kodu yazmanın başka bir riski ise şöyledir : Yazılımda kullanılmayan kodlar birikir ve bu zamanla bir yığın haline gelir. Bu belki yavaşlamalara sebebiyet verir ve bu yüzden de hatalar oluşur. Sonra bu hatayı bulmak için debug yapmakla zaman kaybedebilirsiniz. Kuralı bu şekilde genişletebiliriz.

    "Gerçekten ihtiyaç duymayıncaya kadar kodu yazma, kullanılmayan tüm kodları sil."
 
     İhtiyacınız olmayan kodlardan kurtulmalısınız. İhtiyacınız olduğunda onları tekrar ekleyebilirsiniz. Başka bir yazıda bunla ilgili yine bir şeyler okumuştum. Eskiden github tarzı yapılar yokken kodun yorumlanması bir şekilde anlaşılabilirdi, fakat günümüzde bu tamamen gereksizdir. Çünkü istediğiniz kodu istediğimiz zaman github vb araçlar üzerinden bulabilirsiniz. Ama nedense biz bu hastalıktan hala kurtulamıyoruz. Aman silme, yorum yap belki ileride lazım olur. Bir şey olursa değiştiririz. Yapılarımız maalesef o kadar hassas ve kırılgan ki kesinlikle hiç bir şeye dokundurtmuyoruz. Bu da belirli bir zaman sonra o yazılımda değişiklik yapmayı imkansız kılıyor. Sonrası malum ...

    İhtiyacı olmayan kodu yazmanın veya gereksiz kısımları silmemenin bir kaç sebebi var. Bunlardan ilki, bazı insanlar kullanıcının her istediği özelliği hazırlayarak ileride gelebilecek değişikliklerden kurtulmak isterler ama bu yanlış, çünkü böyle bir şey mümkün değildir. Her daim güncellemeler olacaktır. Bunu önceden çözmeye çalışmak doğru bir şey değildir.

    Diğerleri ise, ileride yapacakları işten kurtulduklarını sanırlar. Gerçek böyle değildir. Eğer o koda ihtiyaç dahi duyulsa onun tekrar tasarlanması lazım ve bu da yine zamanınıza mal olacaktır.

   
Değişiklik için kodu basitleştirmemek: Yazılım projelerinin ölümcül problemlerden biri de "katı tasarım"dır. Yazılımcı kodunu yazdığında değiştirmesi çok zordur. Tasarımın katı olmasının 2 sebebi şöyledir:
  1. Gelecek hakkında tahminler yürütmek
  2. Tasarımsız kod yazmak
     Katı tasarımdan kaçınmak için kural şöyledir "Kod ilerideki tahminlerinize göre değil, şimdiki bildiklerine göre tasarlanmalıdır."

     Kod,şuana odaklanmalıdır, şuanda istenilen talepler göz önüne alınmalıdır, ilerde olacaklar değil. Şuan gerçekten X özelliğine ihtiyacınız varsa , sadece onu geliştir. Kafanızı başka şeylerle dağıtmayın. İleride bununla ilgili ne gibi değişikliler olur diye düşünme. Sadece o an istenilene enerjinizi harcayın.

      Bu planlamanın kötü olduğu anlamına gelmez. Yazılımda belirli bir tasarım çok değerlidir. Ancak detaylı planlar yapılmadığı vakit, kodun küçük dokunuşlarla rahatlıkla değiştiğini ve bilinmeyen özelliklere kolayca adapte olduğunu göreceksiniz. Burada bahsedilen her şeyi mükemmel bir şekilde tasarlayacağım ve bir daha burası değişmeyecek şekilde kafa yorulmaması gerektiğini anlatılıyor. Çünkü değişim kaçınılmaz olduğu için böyle keskin planlar yerine esnek bir yapı kurmak gerektiğini anlıyorum.

     Çok genel olma: Bir problemle karşılaşıldığında, bazı yazılımcılar bunu çok genel bir yapı ile çözebileceklerine inanırlar, biz buna "aşırı mühendislik" diyoruz. Sözlükte aşırı çok çok anlamına , mühendislik ise tasarım ve inşa etmek anlamına gelmektedir. Bir saniye bu kulağa güzel bir şey gibi gelmiyor mu ?

     Evet, projelerin çoğu bunu kullanır. Karınca yuvasını yıkmak için lazer ışını kullandığınızı düşünün. Buna gerek var mıdır ? Ayrıca bunun maliyeti oldukça fazladır.  Sistemi kurması zordur, bakımı ise tam bir kabustur. Program hata verdiğinde o problemi çözmeyi hayal edebiliyor musunuz ?

    Burada aşırı mühendislik üzerine bir kaç problem var
  1. Geleceği tahmin edemezsin. Ne kadar dinamik bir yapı oluşturmak isteseniz de bu ilerideki talepler için sizi tatmin etmeyecektir. 
  2. Kodunuz çok dinamik olduğunda , kullanıcı tarafından hataları anlaması da zorlaşır. Ör; bütün girdileri aynı tipten aldığınızı düşünün. Bir bakıma bu iyi bir şeydir. Basittir, küçüktür vb özellikler içerir, fakat bu sizin kodunuzu karmaşıklaştırır. Tüm girdiler aynı olduğu için , metin olan dosyalar ile fotoğraf dosyaları aynı yerden olacaktır. Bir hatayla karşılaştığınızda ikisinde de aynı hatayı verecektir. Bu da kullanıcının hatayı anlamasını engelleyecektir. 
  3. Çok genel kod yazmak ,bizi ihtiyacımız olmayan kod yazmaya yönlendirecektir. O da bizi ilk adımdaki hataya yönlendirir. 
     Genel olarak, basit tasarımlar yerine karmaşık tasarım yaptığınızda siz aşırı mühendislik yapıyorsunuz demektir. Yukarıdaki karınca yuvası örneğindeki gibi , eğer siz karınca yuvasını yakmak için lazer kullanıyorsanız aşırı mühendislik yapıyorsunuzdur. Bunun yerine basit bir zehir ile de bu işi çözebilirsiniz. Genel tasarımlar iyi olabilmekle birlikte , farklı zorlukları da vardır. Bu yüzden kuralımız şöyle olmalıdır.
 
     "Sadece ihtiyacınız olduğu kadar genel yapı kullanın."

      Artan Geliştirme ve Tasarım:  Doğası gereği yukarıda anlattığımız kusurlar yazılımda vardır. Buna çözüm de vardır.  Sistemi parçalamak ve  o şekilde inşa etmeye başlamak. Bunu en iyi bir örnekle açıklarız. Basit bir hesap makinesi tasarımı yapmaya çalışalım.

  1. Sadece toplama işlemi yapan bir tasarım yapın.
  2. Bunu sisteme uygulayın
  3. Şimdi buna basit olarak çıkarma işlemi de ekleyin.
  4. Şimdi çıkarma işlemi de sisteme uygulayın. Sadece toplama ve çıkarma işlemleri mevcut.
  5. Sistemi tekrar düzenleyin. Kolayca çarpma işlemini de uygulayın.
  6. Sisteme çarpma işlemini de uygulayın. Toplama , çıkarma , çarpma işlemleri mevcut.
  7. Sistemi düzeltin ve bölme işlemini de kolaylıkla uygulayın. (Bu işlem oldukça az çaba harcanmalıdır. Çünkü daha önce çıkarma ve çarpma işlemleri için sistemi tekrardan gözden geçirmiştik.)
  8. Bölme işlemini de uygulayın. Artık sistemi inşa etmeye hazırız. 

      Bu sistem diğerlerine göre daha az çaba ve zaman gerektirir, fakat siz diğer prensiplere alışıksanız ilk başlarda zorlanabilirsiniz. Bunu da pratik yaparak aşabilirsiniz.

     Bu yöntemi uygulamanın en zor yanı belki de bu işleri sıralamaya koymaktır. Biz toplama işlemini ilk başa koyduk. Çünkü bu dört işlem arasında en kolay toplama işlemiydi. Daha sonra da zorluklarına göre çıkarma, çarpma ve bölmeyi ekledik.

     Bu aslında artımlı gelişim ve artımlı tasarım olarak adlandırılan iki yöntemin birleşimidir. Artan geliştirme küçük parçalara bölerek sistemi kurma işidir. Artımlı tasarım ise küçük geliştirmeler sonucu tasarımı gözden geçirip düzenlemektir. Sistemi düzelt ve planla artımlı tasarımın parçalarındandır. Bu yöntem yazılım geliştirme için tabi ki tek yöntem değildir, fakat yukarıda sayılan 3 hataya da önlem almıştır.

     Güzel tasarımlar inşa etmek dileğiyle. Hoşça kalın.     

Hiç yorum yok:

Yorum Gönder