Hepimizin bildiği gibi yazılım geliştirme çok kompleks ve kaotik bir süreçtir. Niyetlendiğimiz işe başladıkdan sonra bile çok sıkça niyet değiştirebiliriz. İsteklerimiz değişebilir, müşteri fikir değiştirebilir ve her şeyi sil baştan yapabiliriz. Zira işe başladıktan sonra kaybedilecek şey sadece zamandır ve zaman da göreceli olarak değersiz görülür. Oysa bir inşaat işine başladığınızda plan dışına çok nadir çıkarsınız, çünkü planı değiştirmek istediğinizde o ana kadar kullandığınız inşaat malzemesini çöpe atmak istemezsiniz o malzemenin ölçülebilir maddi değeri vardır. Ancak müşteri, yazılımın geliştirme safhasında henüz bir şey görmediği için değişiklik isteklerini futursüzca yazılım ekibine iletebilir. Bizler de yazılım geliştiriciler olarak her şeyin bir yolunu bulabildiğimiz için bir şekilde müşteriye ayak uydurmak zorunda kalırız. Bu ayak uydurmalar zaman içinde yazılımımızın kod kalitesini, standardını ve tasarımını bozmakla beraber bir çok kod parçasının nerdeyse tekrar dokunulamaz hale gelmesine neden olmakta.
İşte bütün bu riskleri minimuma indirgemek için daha en başta bazı temel kurallara dikkat etmek ve herkesçe malum olan bazı kötü tasarım ve geliştirme yaklaşımlarından uzak durmak gerekir. Bu sayede geceleri daha rahat uyuyabilir, müşteri taleplerine daha serinkanlı cevap verebiliriz.
Bu yazıda yazılım geliştiriciler tarafından yapılmaması gereken ve sebebi ne olursa olsun (istisnalar hariç olmak üzere) uzak durulması gereken ve ismi konulmuş bir takım kavramlardan ve yöntemlerden bahsedeceğim. Kısacası konumuz : “anti-pattern”.
İşte size adını sıkça duyabileceğiniz yapılmaması gerekenler;
The BLOB ya da The God Class
Bir sınıf düşününki içinde 50’den fazla operasyon ve özellik var. İşte bu sınıfa ilah sınıf diyebilirsiniz. Çünkü muhtemelen uygulamanızın mimarisi bu sınıftan ibarettir. Eğer “Uygulamamın temel mimarisi bu sınıf içindeki operasyonlarda” cümlesini kuruyorsanız bilin ki yanlış yoldasınız ve muhtemelen prosedürel bir yazılım ortamındasınız ya da son derece kullanışlı olan nesne dayalı programlama modelinden uzaksınız. Eğer kodunuzun içinde çokça God Class ya da BLOB var ise uygulamanızın bakımı zorlaşır ve genişleyebilirliği oldukça zor, hatta bazen imkansız olabilir. Doğrusunun ne olduğu ile ilgili nesne yönelimli programalama presinsiplerini incelemenizi öneririm. Unutmayınız ki bu yazıda ne yapmanız gerektiği değil ne yapmamanız gerektiğini inceliyoruz.
Spaghetti Code (Nam-I Diğer Makarna Kod)
“Bu kodda değişiklik yapacağıma yeniden yazayım daha iyi” cümlesini söylediğinizi hatırlıyor musunuz hiç? Eğer hatırladıysanız, o kod bloğunu hayal edin bir anlık, işte o koda spaghetti kod diyoruz. Genellikle her proses (process oriented) için bir fonksiyon yazıyorsanız ve de oluşturduğunuz sınıflar arasında nerdeyse hiç ilişki yok ise makarna kod oluşturmaya eğilimlisinizdir. Eğer bir yerde makarna kod var ise muhtemelen nesne yönelimli programalamnın nimatlerinden türetme ve çok biçimlilik kullanılmamıştır, yeniden kullanılabilirlik (reuse) genellikle bir çok copy-paste içerir. Makarna kod yazmaktan kurtulmak istiyorsanız size bir problem geldiğinde hemen kod yazmayı başlamayın, önce mantıksal bir tasarım yapın.
Cut And Paste Programming (Kes-Yapıştır Programlama)
Biz buna daha çok “Copy-Paste” programlama diyoruz. Daha önce çözdüğünüz bir probleme yazılımınızın başka bir bölgesinde daha ihtiyaç duydunuz ve kodu olduğu gibi kopyalayıp yeni noktaya taşıyıp üzerinde değişiklik yaptınız ya da internette dolaşırken çok iyi bir çözüm buldunuz ve kodu oldugu gibi kendi yazılımınıza aktardınız. Bütun bunlar belli ölçüde makul gibi görünebilir ancak bu yaptığınızın kod tekrarına (code dubplicate) neden olabileceğini asla unutmayın. Eğer kod tekrarı oluşmayacak şekilde copy-paste yapabiliyorsanız ne ala, aksi takdirde “yaaa ben bu hatayı çözümlemiştim 1 ay önce, ne oldu yine!” cümlesini sürekli kurmaya mahkum olursunuz.
Golden Hammer (Altın Çekiç)
Genellikle insani bir zaafiyetten kaynaklanan “Golden Hammer” benim en tehlikeli gördüğüm anti-pattern’dir. Altın Çekiç burada bir ürünü, teknolojiyi ya da spesifik bir mimari modeli temsil edebilir.Örneğin yıllarca “Domain Driven Design” konusunda çalışmalar yapmış bir takım liderinin bütün projeleri ve mimarileri bu eksende oluşturma çabası ya da yeni öğrendiği ve çok hoşuna giden bir veritabanı sistemini projede kullanma zorunluluğu hisstemesi bu semptoma birer örnektir. Aynı şekilde olaya tersten bakarsak mevuct uygulamaların veya mimarilerin yeni geliştireceğimiz sistemlerin mimarisinde belirleyici rol oynamasıda altın çekiç olarak adlandırılabilir. Özetle bu sendromdan kurtulmak için yazılımcının yeniliklere açık olması ve açık görüşlü olması gerekir.
Functional Decomposition (Fonksiyonel Parçalama)
Bilindiği üzere sınıflar nesne dayalı programlama ve tasarımın en temel yapı taşlarıdır. Ancak kodlarımızın içinde yüzlerce sınıf olması yeteri kadar düzgün bir nesne tasarımı yaptığımız anlamına gelmez. Hele de içinde yalnızca tek bir fonksiyon olan ve genellikle bir işi tarif eden sınıf isimleri kullandıysak (ProcessOrder gibi sınıf isimleri) pek muhtemeldir ki fonksiyonel ayrıştırma yapmışız ancak prosedürel bir yaklaşım ile geliştirme yapmışız demektir. Genellikle bu tip sınıflarda “public property ya da değişkenler” az olur ve sınıflarda çok az durum bilgisi tutulur. Hatta çoğunlukla static fonksiyonlar içerir. Genellikle nesne dayalı programalama tekniği aşima olmayan yazılımcıların nesne yönelimli bir platformda kod yazma başladıklarında görülür. Bir C pogramcısının aniden Java ya da .NET platformunda kod yazması bu anti-pattern’e neden olabilir.
Dead End (Ölümcül Son)
Üçüncü parti bir bileşen satın alıp ya da ücrretsiz indirip kullanmaya başladınız. Zaman içinde bazı noktalarda ihtiyaçlarınıza tam çözüm olmadığını anladınız ve başladınız üçüncü parti bileşenin kodlarında değişklik yapmaya. İşte bu noktadan sonra ölümcül sona yaklaştınız demektir. Zira üçüncü parti bileşenin sahipleri yeni bir versiyon ya da güncelleme yayınladıklarında sizin yeni versiyona geçmeniz imkansız hale gelmiş olabilir. Bu yüzden asla üçüncü parti bileşenlerin kodlarında ihtiyacınıza özel kod değişkliği yapmayın ya da herkesçe bilinen ve değişkilik gerektirmeyecek (ama gelişmeye açık olan) üçüncü parti araçlar ve yazılımlar kullanın.
Reinvent The Wheel (Tekerleği Yeniden Keşfetmek)
“Bizim yazılım diğer yazılımlara hiç benzemiyor”, “Biz daha farklı bir teknikle yapmalıyız”, “Bizim problemiz kendine münhasır, başka şeylerle çözemeyiz” gibi düşünceler tekerliği yeniden keşfetmemize neden olan temel düşüncelerdir. Tekerleği yeniden keşfetmemize neden olan diğer konu ise geliştiricilerin başka geliştiricilerin geliştirdikleri sistemler ya da bileşenlerden haberdar olmamasıdır. Günümüzün açık sistem dünyasında her yazılımda kullanılabilecek hem mimari çözüm pratikleri hem de yazılım geliştirme pratikleri mevcut, bu pratikleri düzgün bir şekilde harmanlayıp kullanabiliyor olmak yazılım geliştiricilere zaman kazandırır, yazılım sahiplerine ise kalite ve sağlamlık katar. Siz siz olun tekerleği yeniden keşfetmeden önce tekerliğin başkası tarafından zaten keşfedilip keşfedilmediğini araştırın.
Design By Committee
Gold Plating olarak da bilinen bu anti-pattern yazılım geliştirme ve tasarım sürecindeki bir dizi yanlışları ifade etmek için kullanılır. Kompleks tasarım dökümanları, analiz aşamasındaki kavgalar, sesi yüksek çıkanın kazandığı toplantılar, kalabalık ve anlamsız toplantılar, aynı anda bir çok kişinin tasarım veya analiz dökümanını geliştirmesi, yazılım mimarı ve geliştiriciler arasındaki çatışmalar, isteklerdeki önceliklerin belirli olmaması gbi durumlar yazılım geliştirme sürecini kaotik hale getirdiği gibi, bir anlık bütün ekipleri (komite ) çok ama çok önemli bir iş yapıyoruz yanılgısına düşürür. Genellikle çok konuşulan ama az çıktı üretilen proje ekipler için “Design By Committee” deyimini kullanabiliriz. Bu durumlara düşmemek için iyi bir proje yönteimine, başarılı bir yazılım geliştirme prosesine sahip olmak ve referans projeleri baz alarak ilerlemek gerekir.
Sumo Marriage (Sumo Evliliği)
Yazılım geliştirirken birbiri ile igili ya da ilgisiz iki büyük bileşeni (örneğin veri katamanı ile iş katmanını) birbirinden ayrılamayacak şekilde bir arada kullanmak sumo evliliği olarak bilinir. Uygulamanızın yeni teknoloji trendlerine hızlı bir şekilde adapte olabilmesi için (örneğin servis odaklı mimari ya da bulut bilişimi gibi yeni trendler) sumo evliliğinden kaçınmanız gerekir. Bileşenler yeteri kadar düşünülmüş bir soyutlama ile kullanılmalıdır ve ihtiyaç dahilinde bir bileşenden vazgeçip başka bir bileşene geçiş mümkün olabilmelidir.
Swiss Army Knife (İsveç Çakısı)
Büyük bir çoğunluğumuzun mutlaka bir isveç çakısı olmuştur. İsveç çakısı görünüşte çok faydalı bir alettir ancak ona sahip olduğunuzda asıl gerçeği öğrenirsiniz. Çünkü taşıması zordur, bir çok amaca yönelik tasarlandığı için belirli bir amaç için tasarlanan alete göre kullanım zordur ve arızalandığında tamir etme maliyeti çok daha fazladır. Asıl amacı dışında bir çok iş yapan yazılımlar ve büyük büyük sınıflar klasik birer isveç çakısıdır. Öyle ki, bu yazılımlar öyle kompleks tasarlanır ki çok basit bir kullanım senaryosunda bile deveye hendek atlatmak gerekebilir. Özetle yazılım dünyasında İsveç çakısı benzeri yazılım ya da bileşen geliştirmek kaçınılması gereken bir durumdur.
Architecture By Implication
Yazılım ekipleri geçmişte başarılı bir şekilde uyguladığı bir mimari ya da çözümü doğal olarak yeni projede de kullanma eğilimine girerler. Ancak yeni proje doğası gereği farklı risklere sahiptir ve farklı şekilde irdelenmesi gerektiği gözardı edilir. Genellikle bu anti-pattern kendine çok güvenen ekiplerin olduğu durumlarda ortaya çıkar. Her projenin doğasına uygun bir mimari ve çözüm üretmek gerekirken geçmişi birebir uygulamak yanlışa götürmektedir. Tabi bu geçmiş deneyimlerden faydalanmayalım anlamına gelmiyor. Sadece söylemek istenen geçmiş deneyimlerin (başarılı dahi olsa) yeni projelere doğal bir mimari ve çözüm seti empoze etmemesidir. Aksi takdirde yeni teknoloji trendleri veya yeni pratiklerden sürekli bir uzaklaşma eğilimine girilir.
Vendor Lock-In
Türkçesi ile bir ürüne göbekten bağlı olmak olarak adlandırılacak bir anti-pattern’dir. Yazılımın bir ürüne bağlı olarak çalışması genellikle staratejik bir karar olmakla beraber bir çok risk içermektedir. Bir üreticinin veritabanına göbekten bağlı olmak ya da bir firmanın geliştiridiği bir kütüphaneyi yeteri kadar soyutlamadan kullanmanın o yazılımın geleceğini etkileyen faktörlerden olduğunu bilmek gerekir. Bir üretici ürününü kullanırken bütün riskleri ile analiz edip kullanmak gerekir. Unutulmamalıki her bir üretici sizin gibi ticari bir kuruluştur ve size sormadan ürününü geliştirmeyi bırakabilir ya da farklı bir yöne kayabilir. İyi analiz edilmeden kullanılan bir çok üretici ürünü yüzünden çöpe gitmiş ya da gimek üzere olan bir çok projenin olduğunu rahatlıkla söyleyebilirim.