Kaliteli Yazılım Tasarımı ve Anti-Patternler Üzerine Notlar

Prof. Dr. Deniz Kılınç
Aykiri Yazilimcilar
5 min readMar 20, 2020

--

Yazılım Tasarımı ve Anti-patternler…

Photo by Alessandra Onisor on Unsplash

1. Kaliteli Yazılım Tasarımı Deyince?

Kaliteli yazılım tasarımı başlı başına incelenmesi gereken bir konu olsa da yıllardır sektörde çalışan ve işin içerisinde acı-tatlı tecrübelere sahip yazılım geliştiricilere “Kaliteli yazılım tasarımı sizce nedir / nasıl olmalı?” şeklinde bir soru sorduğumuzda muhtemelen aşağıdaki cümleciklerden ve anahtar kelimelerden söz ettiklerini işitiriz.

  • Basitlik olmalı yani basit yazılmış ve değiştirilebilir kod altyapısına sahip olmalı (Maintainable).

→Kod parçaları okunabilir olmalı (Readability).

→Tasarım genişleyebilir olmalı (Extendable).

→Yüksek kohezyon önemli: Sadece kendi işini yapan kod parçaları (sınıflar, fonksiyonlar) olursa, nerede iş yapacağımıza kolay karar veririz.

  • Yazılan kod parçaları tekrar kolayca kullanılabilmeli (Reusability).
  • Yazılan kod parçaları kolayca test edilebilmeli (Testability).

→ Örneğin: Kolay birim test yazılabilmeli.

  • Kodda değişiklik yaptığımızda üründeki diğer kod parçalarının minimum seviyede etkilenmesi (Minimum regresyon hatası/etkisi). Yani sınıflar arası minimum bağımlılık olması (Dependency ya da Coupling).

Yazılım kalite ölçütleri olarak adlandırılabilecek bu anahtar kelimelerin (readability, testability, usability, coupling, cohesion, dependency vb.) önemli bir kısmı, yazılım tasarım prensipleri ve kalıpları ile doğrudan ya da dolaylı şekilde ilişkilidir. Bu noktada yazılım tasarım prensiplerine ve kalıplarına direk olarak dalmadan önce yazılım tasarımında kalite düşmanı olarak niteleyebileceğimiz (tecrübeyle sabit) anti-patternleri incelemek daha sağlıklı olacaktır.

2. Anti-Patternler: Yazılım Tasarımında Kalite Düşmanları

Anti-pattern’ler, yazılım geliştirme sürecinde kullanımlarının (eskiden) iyi olduğu düşünülen “(eski/yeni) kötü pratikler” olarak adlandırılabilirler. Farklı kaynaklarda “dark pattern” ya da “pitfall” olarak da geçen bu kavram, Bell Labs programcısı Andrew Koenig’in C Traps and Pitfalls adlı kitabında bahsetmesiyle yaygınlaşmıştır. Yazılım tasarımı, kodlama ve proje yönetiminde sıkça karşılaşılan (ve başımıza çok iş açıp sürekli eski yazılım geliştiriciyi anmamıza neden olan) bazı anti-pattern’ler aşağıdaki gibi sıralanmıştır.

2.1. Sihirli Düğme (Magic PushButton)

Herhangi bir soyutlama yapılmaksızın, görsel bileşenlerin (olaylarının / events) arkasında tüm kodlamanın yapılmasıdır. Bu yaklaşım “buton-click” programcılığı olarak da adlandırılmaktadır. Özellikle GUI (Graphical User Interface) tabanlı uygulamalarda daha fazla görülür (Örneğin, Windows Forms Programlama). Özetle; ara yüz tarafı ile iş mantıkları genellikle buton gibi bir bileşenlerin arkasına gömülür.

2.2. Spaghetti Kodlama (Spaghetti Coding)

Bakım ve değişiklik yapılamayacak kadar karmaşık yazılmış kodlama türüne bu ad verilmektedir. Nesne yönelimli olmayan dillerde daha sık rastlanan bir durumdur. Metotlar bir sürecin tamamını gerçekleştirmek için yazılırlar. Çoğu metot parametre almaz ya da tam aksine çok fazla parametre alır. Kodun yeniden kullanılabilirliği zordur. Nesne Yönelimli Programlama (NYP) kullanılıyorsa bile NYP temel özellikleri (kalıtım, çok biçimlilik, soyutlama) doğru kullanılmamıştır. Goto vb. komutlar sebebiyle, kodların incelenmesi imkânsız hale gelebilir. Diğer bir örnek de istemci ve sunucu tabanlı kodların birbiri içerisine girmesi olabilir.

2.3. Lazanya Kodlama (Lasagna Coding)

Gereğinden fazla sayıda katmana sahip uygulama geliştirilmesine verilen isimdir (Aşırı çok katmanlı uygulama). Çok katman ve çok sayıda irili ufaklı sınıf kullanılarak tasarlanmış bir yazılım uygulamasının anlaşılması ve değiştirilmesi zordur.

2.4. Kopyala -Yapıştır Programlama (Copy-Paste Programming)

Daha önce yazılmış kodları, sürekli farklı yerlere kopyalayarak yapılan yazılım geliştirme verilen isimdir. Yazılımda daha önce uygulanan bir kod bloğunun, ihtiyaç olunduğu düşünülen başka bir yerde birebir kopyalanarak kullanılmasıdır (ufak revizyonlar yapılabilir). Bu anti-desen, kod tekrarı yapılmasına neden olarak, kopyalanan kodda bir değişiklik ihtiyacı olduğunda, kodun çoğaltıldığı tüm yerlerin de değiştirilmesini neden olur. Yazılım güncellemeleri için harcanan zaman artar. Hatalar gözden kaçabilir ve uygulamanın yanlış çalışma riski giderek artabilir.

2.5. Tanrısal Nesne (God Object)

Gereğinden fazla iş yapabilen sınıflara bu isim verilmektedir. Bu sınıflar çok fazla üyeye ve davranışa sahip olup, uygulamanın ana sınıfı gibi algılanabilmektedirler. Bu kötü bir tasarım yaklaşımıdır ve (neredeyse) tüm iş mantığını barındıran bu sınıflarda değişiklik yapmak imkansızdır. Yazılım karmaşıklığına ek olarak, bu nesnelerin belleğe yüklenmesi zaman alır.

2.6. Altın Çekiç (Golden Hammer)

Daha önceden bildiğimiz bir tasarım yaklaşımının mükemmel bir çözüm olduğuna inanıp, her sorunu aynı yöntemle çözmeye çalışmaktır.

“Elinde çekiç olan birine tüm sorunlar çivi gibi görünür.”

Farklı problemler farklı çözüm yaklaşımları gerektirebilirler. Fakat işin içerisinde sahiplenme söz konusu olduğu için bu durumu aşmak kolay değildir (alışkanlıklar ve egoyu bir kenara bırakmak zor). Örneğin tüm yazılım problemlerinde aynı mimari desenini kullanmaya çalışmak yanlış bir yaklaşımdır. Özellikle eski yazılım projelerinin (legacy) devir alındığı süreçlerde, önceki yazılımcıların ürettiği projelerin alt yapılarına serzenişte bulunmak işin doğal bir parçası haline gelmiştir.

2.7. Tekerleği Yeniden Keşfetme Eğilimi (Reinventing the Square Wheel)

Günlük hayatta hemen her problemin algoritmasının bilindiği bir dünyada, bu çözümleri bilerek ya da (bilmeyerek) görmezden gelerek, yeni çözümler üretme çabasına verilen isimdir. Bu yaklaşımın arkasındaki niyet iyi olsa da sonuçları genellikle hüsrandır. Örneğin veritabanına erişim katmanında kullanabileceğimiz onlarca ORM (Object Relational Mapping) aracı/çatısı varken, kendinizin sıfırdan böyle bir çatıyı yazmaya kalkışmanız mantıklı değildir (2010 yılında olsak neyse).

8. Aşırı Mühendislik (Over Engineering)

Özellikle proje yönetimi kategorisinde incelenen bir anti-pattern türüdür. Bir ürünün ihtiyaç olmadığı halde gerekenden daha sağlam ve daha fazla özelliğe sahip olacak şekilde tasarlanması ve haliyle gerekenden daha fazla kaynak harcanması şeklinde tanımlanabilir. Basitlik ilkesi ve startup ürün geliştirme sürecinde kullanılan MVP (Minimum Viable Product) yaklaşımları ile tamamen çelişmektedir.

MVP: Piyasa sürülmek istenilen bir ürünün en önemli ve etkili (pazarlanabilir) temel özelliklerinin, en az maliyetle (zaman, kaynak) yapılması ve mümkün olduğunca ortaya yalın bir ürün çıkartılmasıdır.

9. Analiz Felci (Analysis Paralysis)

Geleneksel yazılım yaşam döngülerinin bazılarının (Waterfall- Çağlayan yaşam döngü modeli) da temel odağına yer alan ve analiz sürecinin olması gerektiğinden çok daha fazla önemsendiği durumdur. Bazen detaylar o kadar önemli hale gelir ki kritik kararlar atlanabilir. Analiz maliyeti de doğal olarak çok yüksektir. Yazılım yaşam döngüsünde bir sonraki adıma geçilmesinde zorluk yaşanır. Özellikle Çevik (Agile) yazılım geliştirme yaklaşımlarında yer alan “çalışan bir yazılım, detaylı belgelendirmeden/dokümantasyondan daha önemlidir” manifesto maddesi unutulmamalıdır.

Şimdilik bu kadar, tekrar görüşmek dileğiyle…

Not: Anti-patternler ile ilgili ayrıntılı inceleme için Burak Selim Şenyurt’un aşağıdaki yazısını incelemenizi tavsiye ederim.

Referanslar

  1. https://www.buraksenyurt.com/post/AntiPatterns-Ders-Notlarc4b1m
  2. https://exceptionnotfound.net/
  3. https://nevraa.com/2012/06/22/anti-patternbuyuk-sorunla/
  4. http://agilemanifesto.org/principles.html

--

--

Prof. Dr. Deniz Kılınç
Aykiri Yazilimcilar

Professor at Bakırçay University, Industry experience in software engineering and data science for 23 years. Founder of https://kalybeai.com