Makale Özeti

Merhaba Arkadaşlar, kaldığımız yerden devam ediyoruz. Bir önceki yazımızı temel mimari katmanlarına kısaca değinmiştik. Bu yazımızda bir uygulama için mimari hazırlarken hangi parameterelere bakmamız gerektiğini nelere dikkat edilmesi gerektiğine değineceğiz.

Makale

Yazılım Mimarilerinin Temel Prensipleri -2

Merhaba Arkadaşlar, kaldığımız yerden devam ediyoruz. Bir önceki yazımızı temel mimari katmanlarına kısaca değinmiştik. Bu yazımızda bir uygulama için mimari hazırlarken hangi parameterelere bakmamız gerektiğini nelere dikkat edilmesi gerektiğine değineceğiz.

 

Konuya girmeden önce size bir sunumda karşılaştığım Sarah Winchester House'dan bahsetmek istiyorum. Evin hikayesi oldukça ilginç. Hikayesi kadar evin yapısı ve yapılış şeklide bir o kadar ilginç. Asıl dikkatinizi çekmek istediğim bir nokta evin mimarisi; Evdeki pek çok oda sonradan yapılmış. Evde 160 oda ve 4 kat (Onun en güzel döneminde evin, 7 katı vardı!) 6 mutfak, 40 yatak odası, 19 baca, 40 merdiven, 47 şömine, 52 tepe penceresi, 950 kapı, 3 asansör, 2 balo salonu ve 10 000 pencereyle!  Hiçbir Mimari detaya dikkat edilmeden sonradan eklenmiş. Hiçbir mimari detay dikkate alınmadan sonradan ilavelerde bu hale gelmiş bir yapı. Eğer uygulamalarımızı bir önceki yazımda bahsettiğim gibi bazı temel prensipler doğrultusunda geliştirmediğimiz taktirde uygulamarımızın mimarisi bu evin olmayan mimarisinden farksız olacaktır.

Mimaride modern yaklaşım tasarımın mimar ve developer için ihtayaç duyduğu her şeyi bilmediğini ve geliştirecek olduğunu farz eder. Yani mimaride developer tarafından kullanılacak her nesne mimar tarafından en az  bir sınıf türetilmiş olmalıdır. Böylelikle developer uygulamayı mimar tarafından geliştirilen freamwork üzerinden geliştirme noktasına gelir.

Örneğin; Tip dönüşümü konusuna bakıldığında  bir tipi başka bir tipe dönüştürmenin pek çok yolu vardır. Parse,Convert, pointer gibi.. Fakat developer ın bu özelliklerden hangisini kullanacağına karar vermeden mimar tarafından geliştirilmiş Core Custom Convert  methodunu kullanması istenmelidir. Tip dönüşümde hangi tipin hangi tipe nasıl dönüştürüleceği bu Facade methodun arkasında karar verilmelidir.

 

Bunun gibi tüm katmanlarda mimar - developer'ı  geliştirdiği yapılarla sarmalamalıdır. Böylelikle uygulama mimarisi üzerinde tam kontrol sağlanır. Developer ın temel görevi mimar tarafından geliştirilmiş yapıları kullanarak Uygulamayı geliştirmektir. Böylelikle Uygulama .NET Framework üzerine inşa edilmiş şirket Framework'ü üzerinde yapılacaktır.

Open Closed Prensibi : Şirketin uygulamanın üst versionlarında yapacağı teknolojik politika değişiklikleri min. kodlama maliyeti ile Uygulamaya aktarılabilir. Uygulama ile Şirket Framework'ü (kod geliştirme kültürü) arasında gevşek bağlılık olacağı için de politik değişiklikler şirket Framework'ü üzerinde yapıldığında Uygulama tarafında bir geliştirme ihtiyacı duyurmamalıdır. Bu Prensipbe Open-Close diyoruz.(Gelişime açık ama değişime kapalı) Geliştirdiğiniz mimari üzerinde kullanılmakta olan bir method un dönüş tipi ve parametrelerin tipleri ve sayıları üzerinde asla değişikliğe gitmemelisiniz. İhtiyacınız bunu gerektiriyorsa mu method un aşırı yüklenmiş bir versionun geliştirmeniz önerilir. Böylelikle yeni version yapınızda eski versionunuzu destekleyerek yeni version bir sürüm çıkartmış olursunuz.

Data Access Layer'ınızın ilk versionunda sadece string SQL kullanmış olabilirsiniz. 2.0 Versionun da aynı method un farklı parametre tiplerinde genişletmek mümkündür. Alt version katmanınızla etkileşen diğer katmanlarınız budan etkilenmeyecektir.

 

Uygulama geliştirme safhasında hangi işlemin Mimariye hangi işlemin Uygulamaya ait olduğunu ayırt etmenin basit bir yolu vardır. Bir şirketin aynı anda birden farklı 2 ürün geliştirdiğini varsayalım. Bu ürünlerin ortak parçaları (değişmeyen parçaları) mimarinin bir parçası değişen parçaları da Uygulamaya özgü parçalarıdır. Hemen bir örnekle açıklayalım; Örneğin bir uygulamada Konfigrasyon verisi okumak yada veritabanında bir işlem yapmak Uygulamanın değil mimarinin görevidir. Mimar bu işlemi yapacak olan standar methodları ve tipleri geliştirerek developer a sunar. Developer bu tipleri ve methodları kullanarak konfigrasyon verisini elde eder yada veritabanında işlemini yapar. Fakat developer konfigrasyon verisini nerden okuduğunu yada hangi veritabanına eriştiğini eriştiği veritabanının tipini versionunu bilmez. İhtiyacı olan veriyi elde etmek için optimum standartlıkta bir talepte bulunur. Böylelikle mimarın geliştirmiş olduğu bu yapılar ürün tipi değişse bile değişmeden kullanılacaktır.

Aşağıdaki UML şemasında bunun bir örneğini görmektesiniz.

 

Temel Tasarım Prensipleri;

1- Separation of Concerns (İlişkilerin Ayrılması) : Uygulamanızı mümkün olduğunca küçük fonksiyon parçalarına ve fonksiyon kümelerine bölmelisiniz. Burda önemli olan faktör uygulamadaki tüm bağlantı noktalarında  yüksek uyum ve gevşek bağlılıkta minimizasyona ulaşmaktır.Ancak fonksiyonların ayrılmasındaki yanlış sınırlar sonucun yüksek uyum ve karmışıklık arasındaki özellik hatta özellik içinde içerdiği işlevler içinde anlamlı bir biçimde örtüşmemelerini sağlamalıdır.

2- Single Responsibility (Tekil Sorumluluk):  Her komponent yada modül yanlızca bir tek spesifik görev yada  fonksiyonellikten yada fonksiyonellik kümesinden sorumlu olmaldır.

3- Princible of Least Knowledge (Min  Bilinirlik Prensibi): Uygulama katmanların birbiri ile etkileşirken birbirleri hakkında mümkün olduğunca az bilgi ve ilgi bütünlüğü ile etkileşmeleri ger
eklidir. Bu amaçlar çoğunlukla facade methodlar ve Interfaceler kullanılır.

Önemli olan log mekanizmasında logu yazan mekanizma ile logun içeriğini sağlayan mekanizma tek bir methodla etkileşip bilgi alışverişini sağlamalıdır. Loglama yöntemi ne kadar değişirse değişsin. Bu alışverişi sağlayan method bu değişimden asla etkilenmemelidir.


4- Don't Repeat Yourself (DRY) (Kendini Tekrar Etmeme):  Aynı görevi icra eden birden fazla yapı yada component olmamalıdır.

Abstract bir Class dan türeyen 2 class üzerinde abstract class da geliştirilmemiş bir fonksiyon ihtiyacı varsa bu iki class içerisinde de yazılmamalı yazılan fonksiyon abstract class a indirilmelidir.


5- Minimize upfront design (Açık Tasarımın Minimize edilmesi): Bazı durumlarda uygulamanın ön kısmında hemen UI kısmında tüm kodunuzu yazarak uygulamanızı geliştirirsiniz. Bu durumda geliştirme maliyetinin yüksek ve hata riskinin fazla olması kaçınılmazdır. ( Bu yönteme günümüzde buton altı programcılıkda diyorlar.) Bir başka durumda da özellikle Agile (Çevik) geliştirme süreçleri için ön katmanlarda geniş geliştirmeleri önlemelisiniz. Eğer uygulama gereksinimleriniz belirsiz yada tasarımınız zaman içerisinde sürekli  değişebiliyorsa, ön tarafta geniş tasarım oldukça efor ve maliyet gerektiren bir süreç olacaktır. Anahtar ilkemiz parçala ve yönet olmalıdır.

Bir uygulama yada sistem geliştirirken mimari manzara  karmaşıklığın farklı katmanlara doğru daha miminize edilmesi üzerine olmasıdır. Örneğin Kullanıcı arayüzü, iş katmanı ve veri erişimi görev ve sorumlulukları birbirinden bütünüyle ayrılmalıdır. Her parça ( Katman yada Component) sadece kendi görevine odaklanmalı ve farklı katmanların görev yada sorumluluğu içermemelidir. UI kesinlikle direk veri kaynağına (Veritabanına, dosyaya, konfigrasyon verisine ) erişmemelidir.

Tüm bu ilkeler bize daha yönetilebilir , kolay kurulabilen, hızlı test edilebilien ve min özelleştirme maliyeti ile sunulabilen ürünler uygulamalar geliştirmemize yardımcı olacaktır.

Bir sonraki yazımızda Uygulama Uygulama Tipine , Kurulum Stratejilerine ve diğer yardımcı parçaların tasarlanmasına nasıl karar verilmesi gerektiği konuları üzerinde duracağız. Her türlü sorularınızı mail adresim aracılığı ile paylaşabilirsiniz. Görüşmek üzere.


Tarık Gökhan Kızılırmak
tarikgokhan@gmail.com