Karmaşık Yazılım Oluşturmanın Genel Sorunları

19 Oca

Karmaşık yazılımlar denildiğinde akla gelen ilk yöntem Domain Driven Design (DDD) olur. DDD yaklaşımını etki alanına dayalı yazılım olarak tercüme edilebilir. Etki alanı demek üzerinde çalışılan sektör ya da bölüm olarak düşünülebilir. Örneğin finans, e-ticaret, hastane, hava yolu, demir yolu vs gibi alanlar yazılımlar için etki alanları ya da Domain’ler olarak adlandırılabilir.

Etki Alanına Dayalı Tasarım (DDD), Eric Evans tarafından “Domain Driven Design: Tackling Complexity in the Heart of Software” adlı eserle ortaya atılan bir geliştirme felsefesidir. DDD, ekiplerin karmaşık sorun etki alanları için yazılımın geliştirilmesi ve bakımının etkin bir şekilde yönetmesini sağlayan bir yazılım geliştirme yaklaşımıdır. Bu yöntem bir programlama paradigması veya kodlama yöntemi değildir. Bu yöntem kodlamadan önce, çalışılacak iş ortamını(domain) tanımak, çalışma alanındaki gerçek dünyayı anlayarak düzgün bir şekilde tasnif etmektir diyebiliriz. Yazılımda yaşanan sorunların çoğu domain içinde saklıdır.

Karmaşık yazılımın zorlukları

Heyecanla ve pembe hayallerle başlanan karmaşık iş uygulamalarının modeli, zamanla en popüler yazılım mimari tasarım modeli olan Big Ball of Mud (BBoM) modeline dönüşür. Bu model Brian Foote ve Joseph Yoder tarafından yazılan bir makalede “gelişigüzel yapılandırılmış, özensiz, koli bandı ve balya teli yumağı, spagetti kodu ormanı” diye tarif edilmiştir. Bu modelde ayırt edilebilir mimariye sahip olmayan uygulamalar için kullanılır. (Bir tabak spagettiyi hayal edebilirsiniz.)

Şekil-1 de görüldüğü üzere yazılımdaki karmaşanın iki sebebi vardır.

  • Yazılımın karmaşık ve yönetilmesinin zor olmasının ana nedenlerinden biri, alan karmaşıklıklarının teknik karmaşıklıklarla karıştırılmasıdır.
  • İş akışındaki rutin değişiklikler ve küçük özellik geliştirmelerinin, mevcut kodu okuma ve anlamadaki zorluklar nedeniyle uygulanmasının zor olması.
Şekil-1 Yazılımdaki karmaşıklık.

Ortak Bir Dil Olmadan Oluşturulan Kod

İş uzmanlarıyla çalışan ekiplerin domain ortamında kullanılan kavramları, zengin kelime dağarcığı ile doğru bir şekilde yazılım ekiplerine aktarması gerekir. Aksi halde yeni domain kavramları ortaya çıkarılamaz veya geç ortaya çıkarılır maliyetler artar. Bu noktada, iş uzmanları ile geliştirme ekipleri arasında ortak bir dil oluşur. Ortak bir dile odaklanma eksikliği ve sorunlu domain bilgisi neticesinde, çalışan ancak işletmenin amacını ortaya çıkarmayan bir kod tabanı ortaya çıkar. Bu, kod tabanlarının okunmasını ve yönetilmesini zorlaştırır. Çünkü analiz modeli ile kod modeli arasındaki çeviriler maliyetli ve hataya açık olabilir. Sonuçta işletmenin analiz modelinden uzaklaşan kod yapısı ile uygulama bir BBoM modeline dönüşebilir.

İşletme analiz modeli nedir?

Yazılımın nasıl inşa edildiğini anlamak için teknik olmayan kişilerin kavramsallaştırabileceği yazılımın temsilidir. UML gibi modelleme dilleri kullanılarak temsil edilebilir. Bir yazılım uygulamasının mantıksal tasarımını ve yapısını tanımlamak için bir analiz modeli kullanılır.

Organizasyon Eksikliği

BBoM’ye dönüşen bir sistemin ilk üretimi çok hızlıdır. Belli bir domain etrafında kavramsallaştırılmamış uygulamalarda yeni geliştirmeler eklemek veya var olan özellikleri değiştirmek zahmetlidir. Kod tabanı, değişikliği yönetilebilir kılmak için iş davranışıyla gerekli uyumdan yoksundur. Problemin karmaşıklığı, teknik çözümün karmaşıklığı ile karıştırılır.

Şekil-2 Kod çürümesi.

BBoM Deseninin Gelişimi Engellemesi

Spagetti benzeri bir desenle ısrar etmeye devam etmek, özellik geliştirme hızını yavaşlatır. Kod tabanının anlaşılmaz karmaşası nedeniyle, ürünün yeni sürümleri çıktığında hatalar oluşabilir. Zamanla, geliştirme ekibi böylesine bir karmaşa içinde çalışmanın zorluğundan giderek daha fazla şikayet eder. Projeye iş gücü kaynakları eklense bile hız, işi tatmin edecek seviyeye çıkarılamaz. Sonunda, durumdan bıkmış olarak, uygulamanın yeniden yazılması talebi kabul edilir. Başlangıçta hızlı geliştirilen ve teslim edilen uygulama, sonuçta olarak bir kabusa dönüşür.

Problem Alanına(Domain) Odaklanamama

Üzerinde çalıştığınız iş alanını anlamadan geliştirdiğiniz projeler başarısız olur. Yazılım projelerinin yapılması zor veya tıkandığı yer kodlama değildir. Kodlama, sürecin kolay bir bölümüdür. Zor olan, üzerinde çalışılan iş alanına faydalı, istekleri tam olarak yerine getirebilen bir yazılım modelini oluşturmak ve sürdürebilmektir.

İş alanınızı anlamaya ne kadar çok yatırım yaparsanız, iş sorunlarını çözmek ve onu yazılımda modellemek için o kadar donanımlı olursunuz.

Problem alanı(domain) nedir?

Problem alanı, üzerinde çalıştığınız ve yazılım geliştirdiğiniz alanı ifade eder. DDD bize karmaşık iş alanları için yazılım oluşturmaya çalışırken, her şeyden önce problem alanına odaklanmayı önerir. Faydalı bir yazılımın ortaya çıkabilmesi için alanında uzman kişiler yazılım ekipleriyle birlikte çalışır. Örneğin, sağlık sektöründe hasta kayıt yazılımı için doktor kadar bilgi sahibi olmaya gerek yoktur. Bilinmesi gereken, ilgili sağlık terimleri, kavramları, farklı departmanların hastalara ne tür işlemler yaptırdığı ve doktorların hastalardan neler talep ettiğidir.

Kaynaklar

  • Patterns, Principles, and Practices of Domain-Driven Design
  • Domain-Driven Design: Tackling Complexity in the Heart of Software

Domain Driven Design ne zaman uygulanmalıdır

28 Şub

Bir önceki yazının konusu Domain Driven Design(DDD) konulu bir kitap tanıtımıydı. Bu yazıda DDD yaklaşımının hangi durumlarda kullanılması gerektiğini bir kaç cümleyle özetlemeye çalışacağım. Yaklaşımın özelliklerini daha ilerki yazılarda fırsat buldukça anlatmaya çalışacağım.

Domain Driven Desing(DDD) kavramı karmaşık problemlerin küçük parçalara bölünerek ele alınmasını amaçlayan bir yaklaşım tarzıdır. Karmaşık problemlerin parçalara ayrılması da aslında çözülmesi gereken bir problemdir. Taleplerin alınması, iş kurallarının
belirlenmesi ve taleplerin yazılım terminolojisine uygun hale getirilmesi sürecin başlıca gereksinimlerdir. DDD birbiriyle ilişkili iş kurallarının ele alındığı bir yöntem olması sebebiyle çok geniş kapsamlı kurumsal yazılımlar geliştirirken uygulanması gereken bir yaklaşımdır. Örneğin hava yolu rezervasyon sistemleri, e-ticaret uygulamaları, bir devlet kurumu bünyesindeki otomasyon sistemleri şeklinde örnekler verilebilir. İş kurallarının sık olarak değiştiği ve taleplerin sürekli artacağı öngörülen yazılım sistemleri için yazılımın geleceğine aydınlık bir altyapı tasarlamak amacıyla uygulanabilir. Örneğin kanun ve yönetmeliklerin çok sık değiştiği  kurumlarda geliştirilen yazılımları gibi. Ancak karmaşık iş kuralları olmayan basit sistemler için DDD uygulamak uygun olmaz. Örneğin blog sayfaları veya ürün tanıtım amaçlı web projeleri için DDD uygulamak uygun değildir. Bu tür uygulamalar sadece  veri erişimi ve görüntülemesi amaçlanmıştır. Bu tür uygulamaları veriyi kullanıcı ara yüzüne direk aktaran teknikler ile geliştirmek mantıklı bir seçim olacaktır. Aksi taktirde  basit olan bir çözümü, karmaşık hale getirmiş oluruz.

Domain Driven Design Servisleri

11 Oca

Bir domain model için en önemli yapı taşlarından biri servislerdir. Servisler, modele ait Entity ve Value nesnelerinin yapısına aykırı davranışları kendi bünyesinde taşıması için tasarlanırlar. Böylelikle Entity ve Value nesnelerinin vazifesi olmayan işleri yüklenmesini önlemiş olurlar.

Eric Evans‘a göre iyi tanımlanmış bir servisin belli karakteristik özellikleri vardır. Bunlar:

  • Domain nesnelerinin doğal bir parçası olmayan işlemleri yönetir.
  • Domain modelin diğer elemanları açısından Interface’ler tanımlanır.
  • Servis işlemler belli bir yerde tanımlanmak zorunda değildir.

Servisler test edilebilir olması ve birbirine bağlı işlemleri belirleyici olması açısından mutlaka bir  Interface çatısı altında bulunmalıdır. Interface’ler servislerin sözleşmeleridirler.

Servisler Application, Domain, Infrastructure gibi birçok katmanda bulunabilir.

Infrastructure servisleri IEmailSernder gibi dış kaynaklarla iletişimi sağlayan servislerdir. Dış kaynaklar  dosya sistemleri, SMTP, veritabanı, SMS gibi yapılar olabilir. Domain katmanı bir bildirimin kullanıcılara nasıl iletildiği ile ilgilenmez, sadece iç süreci tamamlar ve bir olayı(Event) tetikler.

Domain servisleri, küçük parçalar arasında üst seviye işlevselliği sağlayan kooordinatör vazifesindedir.  Örneğin sipariş işlemi için OrderProcessor servisi, para transferi için FundTransferService gibi. Domain  servisleri model için çok önemli olduğundan isimleri ve kullanımları Ubiquitous Language diye adlandırılan  ve kavramsal bir ifade olan domain dilinin bir parçası olmalıdır. Anlamları ve sorumlulukları müşteri ve  domain uzmanı tarafında tutarlı ve mantıklı olmalıdır.

Application servisleri dış ortama açılan servislerdir. Dış ortamdakiler bizim Entity nesnelerimizle doğrudan  iletişime geçemez. Fakat bunları temsil eden nesnelerle iletişime geçebilir. Katmanlar arasında iletişimi  doğrudan domain nesneleri ile yaparsak diğer katmanlar domain yapımız hakkında çok fazla bilgi sahibi olurlar. Application servisleri dış ortamdan gelentalepleri mesaj şeklinde model içindeki süreçlere aktarır. Bu noktada  Messaging Pattern diye adlandırılan yeni bir kavram karşımıza çıkıyor. Messaging Pattern Application  servislerinin kuralı gibidir. Dış ortamdan taleper mesaj olarak alınır ve iç süreç tamamlandıktan sonra sonuç  dış ortama servisler aracılığı ile mesaj olarak verilir. Application servisleri herhangi biriş kuralı içermezler. İş kuralları Domain katmanı için yürütülür.

Tasarıma başlarken genellikle öncelikle Domain ve Applicaiton servislerin oluşturlması ve kullanıcılara sunulacak olan Interface tiplerinin belirlenmesi daha sonra da Test Driven Development ile dış davranışların test edilmesi uygun olacaktır. Kullanıcı bakış açısından senaryoları oluşturup test etmek bize büyük katkılar sağlar. Çünkü yazdığımız kod sonuçta bir kullanıcıya sunulacaktır.

Özet

Domain Service: Domain nesnelerinin doğal yapısına sığmayan işletme mantığını kapsar. Bunlar CRUD işlemleri değildir. CRUD işelmeri repository bünyesinde gelişir.

Application Service: Sistem dışı kullanıcılar için oluşturulur. Örneğin Web servisleri veya Web arayüzleri bu servislerle haberleşirler. Kullanıcılara sunulan CRUD işlemleri burada tanımlanabilir.

Infrastructure Service: Dış kaynaklarla yapılan iletişimler için oluşturulur. (File, SMS, SMTP, MSMQ).

Kaynak:

  • Eric Evans, Domain Driven Design Tackling Complexity in The Heart of Software
  • http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/