18 Aralık 2016 Pazar

S.O.L.I.D Principles

Yazılım geliştirme aşamasında her birimiz birden fazla araç kullanırız. visual studio, eclipse, telerik, devexpress, sql server, oracle db, tfs, svn vs.   Neden ?  İşimizi kolaylaştırıyor, standartlar sağlıyor, güvenilir, kaliteli. Bu yazılım araçlarından beklediklerimiz kendi yazacağımız uygulama içinde geçerli olmalı. Yazdığınız uygulamayı da birileri bir yerlerde kullanıyor olacak. En bize dokunanı ise kodları güncelleyip, geliştirmeler yapacak olanlar, hata ayıklayacak olanlar ise gene biz olacağız. 

Yazılımda kalite ve standartları tariflemek, ortak bir dil haline getirmek için prensipler, bu prensipleri temel alan ve çözüm üreten programlama dili bağımsız tasarım-mimari kalıpları ortaya konulmuştur. 

S.O.L.I.D sınıf tasarım prensipleri ismini içinde barındırdığı 5 temel prensibin baş harflerinden almaktadır. Robert Cecil Martin tarafından dillendirilen bu prensipler şunlardır:



SRP The Single Responsibility Principle Bir sınıfın değişmesi için tek bir sebebi olmalı ve tek bir amaca hizmet etmelidir. İsviçre çakısı yapmamalısınız.
OCP The Open Closed Principle Bir sınıfın var olan özelliklerini değiştirmeden yeni özellikler eklenebilmelidir. Üzerinize yeni bir elbise giymek ile, estetik ameliyatı için masaya yatmak aynı şey değildir.
LSP The Liskov Substitution Principle Türeyen sınıflar, temel sınıfların yerine kullanılabilmelidir. Nerede o eski bayramlar dedirtmemeliyiz büyüklerimize. Canlı bir ördege ihtiyac varken oyuncak bir ördeği sırf oda vıraklıyor diye kümese koymamalıyız.
ISP The Interface Segregation Principle iş yaptıracağınız metodlarınızı ortak iş gruplarına göre arayüzlere dağıtın. Bir telefonun piyasadaki tüm markalarin şarj girişlerini destekleyecek sayıda girişi olduğunu gördünüz mü.Telefon üreticilerini buna zorlamayın.
DIP The Dependency Inversion Principle Sınıflarınız soyutlama ve arayüzler üzerinden birbirlerine bağlanabilmeli ve çeşitliliğe izin vermelidir. Bizden lego parçaları yapmamız isteniyor, yap-boz parçaları değil.

Bu prensiplere uygun yazılım geliştirdiğimiz taktirde yönetilebilir, test edilebilir kod yazmamız mümkün olabilir.

17 Aralık 2016 Cumartesi

AutoMapper Kullanımı




Domain içinde bulunan nesnelerin sunum katmanı üzerinde ViewModel nesneleriyle eşleştirilmesi her zaman sıkıcı bir iş olmuştur.  Ne demek istediğimizi bir örnek ile açıklayalım. Aşağıdaki Customer, Product, Item, Order sınıfları bizim domain modelimizdeki sınıflar olsun.


Bu sınıflardaki bilgiyi sunum katmanına taşımak için modellemelerimizi de aşağıdaki gibi yapalım.


Sunum katmanımız (ASP.NET, MVC, Desktop, console), servis katmanımızdan bir Order bilgisini OrderID üzerinden istesin.  Servis katmanı bu isteği yerine getirebilmek için veri katmanına gidecek, veriyi repository üzerinden domain nesnesi olarak alacak, sunum katmanına gönderirken de sunum nesnesine çevirip gönderecek. Bu çok katmanlı mimari altyapılı uygulamalarda karşılaştığımız klasik bir durum örneğidir.


OrderService sınıfımızı dikkatle incelediğimizde şu anki konumuzla ilgili olmasa da tasarımsal bir problemle karşı karşıya olduğumuzu göreceksiniz. Sınıfın varsayılan yapılandırıcı metodunda (Default Constructor) new OrderRepository() kodu kırmızı kırmızı parlamaktadır.  OrderService sınıfının OrderRepository sınıfıyla sıkı bir bağ oluşturması yerine arayüz (interface) üzerinden bir bağ kurmasını isteriz.  Arayüzler üzerinden oluşturulan bu zayıf bağlarında IOC araçları ile dinamik olarak oluşturulmasını isteriz. 


Neden? Altyapınızda OrderRepository yerine başka bir Repository kullanmak istediğinizde new ile yazdığınız kod satırlarını bulmanız ve değiştirmeniz gerekiyor. Oysa sisteminiz tak-çıkar mantığı ile desteklenen bir yapıda olursa, arayüzü desteklediği sürece herhangi bir başka sınıfı altyapınızda değişiklik yapmadan konfigurasyon değişikliği ile rahatlıkla kullanabilirsiniz (Ör:Ninject, StructMap). Aklımızdan çıkarmamamız gereken prensip (Open Closed Principle) “Programlar geliştirilmeye açık ama değiştirilmeye kapalı olmalıdır.”



GetOrder metodu içerisinde ConvertToOrderView metodunda domain nesnemiz olan Order,
OrderView nesnesine dönüştürülüyor. Bu metod bir extention metod (Genişletme metodları bir tip üzerinde herhangi bir değişiklik yapmadan o tipi kolayca genişletmenize olanak sağlayan bir yapıdır.) olup aşağıdaki gibi yazılmıştır.



Büyük bir projede bu işi yüzlerce domain nesnesi için yaptığınızda işler  en başta söylendiği gibi sıkıcı olabilir. Gerçi sıkılma kavramı değişken bir durum ve AutoMapper da bir yazilim aracı.  Camın içinde muhafazasında duruyor. "Gerektiği halde kullanmayanlar cezanlandirilmaz." yaziyor üzerinde. 


Şimdi camı kıralım ve bu aracı kullanarak kodu yeniden düzenleyelim.  


Ornek uygulamayi Console tipinde geliştirdim. Uygulama kodlarina yazının sonundaki linkten erişebilirsiniz. Console uygulamama  Nuget üzerinden automapper paketini kurdum.

Ardından nesneler arasındaki bağı ServiceStartup sınıfı üzerinden konfigure ettim.  Nihayetinde de nesneleri ConvertToOrderView metodunda automapper üzerinden çağırdım. 


OrderExtensionMethods sınıfı içinde ConvertToOrderView  genişletilmiş metodunun değişimine dikkat ediniz. Ayrıca diğer genişletilmiş metod olan ConvertToItemView metoduna ihtiyacım kalmadığını da görünüz.


Ayni isimli sinif nesneleri birbirlerine direk bağlandi. Order sinifinin OrderDate özeliği ile OrderView sinifinin OrderDate özeliği buna örnektir.  Aşağıdaki örüntülerde kabul edilmektedir.


 <Sınıf ismi> + <Özelik İsmi>              : CustomerName

<Sınıf ismi> + "_" + <Özelik İsmi>     Customer_Name
"_" + <Sınıf ismi> + <Özelik İsmi>     : _ CustomerName
<Sınıf ismi> + <Özelik İsmi> + "_"     :  CustomerName_
"_" + <Sınıf ismi> "_"  + <Özelik İsmi> + "_"     :  _Customer_Name_


Order sinifinda Customer özeliğinin (Properties)  Name özeliği ile OrderView sinifinin CustomerName özeliği birbirlerine bağlandi. Sınıf ismi + Özelik İsmi kalıbını AutoMapper kabul etmektedir. 


CustomerName özelik ismi yerine farkli bir isim mesela Name kullansaydiniz bağlama işlemi bu özelik için gerçekleşmeyecekti. CustomerName olduğu yerde kalsın. Bu durumu göstermek için yeni bir özelik ekleyeceğim. Ismine Tag diyeceğim ve string tipinden olacak.

Amacim isimleri farkli olan özeliklerin nasil bağlanabileceğini göstermek.

ServiceStartup static sınıfının ConfigureAutoMapper  static metodunda  aşağıdaki gibi değişiklik yapıyorum.


Birde önek (Prefix), sonek (Postfix)  almış olan özellikleri nasil bağlariz diye bakalım. Yukardaki gibi zaten bağlayabilirsiniz. Lakin birden fazla özelik sadece önek alarak farklilaşmissa siz hepsine yukaridaki gibi kod yazmak durumunda kalmak istemezsiniz. Bunun içinde aşağıdaki gibi bir kodlamaya gidiyoruz.


Yazimizi burada noktaliyoruz. Kaynak kodlari AutoMapperTutorial linkinden indirebilirsiniz.

28 Eylül 2016 Çarşamba

ASP.NET MVC



2002 yılında ortaya çıkan ASP.NET (Henüz platform değil.), Web Formları olarak da anılır. Temel amacı web  uygulama geliştirme sürecini olabildiğince masaüstü uygulama geliştirme süreçlerine benzetmektir. Bunu yaparken HTML ve HTTP detaylarından sizi soyutlama yoluna gider. Bunuda sunucu taraflı kontrollerle yapmaktadır. 


 

web sayfaları sunucu üzerinden gidip gelirken her bir sunucu taraflı kontrol nesnesinin (asp.net kontrolleri) durumu viewstate  denilen bir teknik/mekanizma kullanılarak saklanır. ASP.NET sayfalarında viewstate bilgisini tutmak için id değeri __VIEWSTATE olan gizli bir input nesnesi oluşturulur ve value değerine de sayfada kullanılan asp.net kontrollerinin durumu  Base64 kodlaması ile şifrelenerek atanır.

 


Yukarıda value özeliğine atanan string/text ifadesinin sayfaya verdiği ağırlık (yerçekimi burada da var.),  asp.net kontrollerinin sayfa üzerindeki miktarı ve işlevine göre büyüme eğilimindedir. Buda hız ve bant genişliğinin her zaman önem arz ettiği web dünyasında bir problem olarak karşımıza çıkmaktadır.

ASP.NET, code-behind denilen mekanizma ile HTTP ile .NET kodunu birbirinden ayırmakta olduğunu söylese de pratikte; uygulama iş katmanı (application business layer) sonuçlarına göre HTML çıktı üretme işi kod kısmında karmaşık kodlamaya yol açabilmektedir .

Sunucu taraflı kontrollerin ürettiği HTML çıktıları üzerinde de kontrolümüz kısıtlıdır. Buda sayfa üzerindeki ihtiyaç duyulanın çok ötesinde bir HTML ile karşıkarşıya kalmamıza sebeb olur. Özellikle nesnelerin ID lerinin üretimindeki karmaşıklık  ve javascript içinde kullanımı zordur. Bu durum sonraki sürümlerde daha derli toplu bir hale getirildi.

ASP.NET için yazılım projelerinin önemli bir özelliği olan test edilebilirlik, teste uygun kod yazımı kavramında da sıkıntılar vardır. Unit Testing için uygun olmayıp, entegrasyon testleri içinde sıkıntılı süreçler söz konusudur.

Gelişim sürecinde karşılaşılan bu problemler ve zaman içinde web standartlarının sürekli gelişimi,
mobil cihazlarla uyumluluk, farklı tarayıcılarla çalışabilme seçenekleri, HTML5'in çıkışı , standartlara uygun geliştirilmiş javascript kütüphaneleri (AngularJS, jQuery, jQuery UI, and jQuery Mobile), Sadece HTML ile değil, bunun yanında JSON , XML, AJAX  ile de çalışmak, RESTFull 
mimarisini desteklemek, birde AGILE ve Test-DrivenBehaviour-driven metodolojileri, tüm bu standartların sonucu oluşan otomasyon araçları ve bunlara uyumluluk derken ASP.NET Web formları da teknoloji dünyasında var olabilmek için gelişecek ve değişecekti. 

2004 yılında Ruby on Rails sahneye çıktı ve ünlüde oldu. Açık kaynak kodlu bu web uygulama geliştirme altyapısı MVC yaklaşımını temel almaktadır (MVC bir tasarım kalıbı olup ASP.NET 'e özgü değildir. Microsoft şirketinin henüz yeni kurulmuş olduğu dönemlerde bu tasarım kalıbı vardı), ORM desteği sağlar (.Net için Entity Framework gibi), yukaridaki paragrafta bahsi geçen Agile, TDD, BDD yaklaşımları ile uyumlu çalışır.

AJAX bize javascript'in önemini gösterdi. JQuery ile kolaylığını ve gücünü gördük. Google'in açık kaynak  kodlu V8 javascript motoru ise hızını ve sunucu taraflı kodlamada da kullanılabileceğini gösterdi (Geliştiriciler tek bir dil -javascript- kullanarak hem istemci hemde sunucu taraflı kodlama yapabilmekteler. ). 2009 yılında ortaya çıkan Node.js  bunun güzel bir örneğidir. ASP.NET MVC' in asenkron kontrollerinde kullanılmaktadır.

2007 yılında Microsoft yeni web geliştirme platformunu duyurdu. ASP.NET artık platform olmuştu. Web form mimarisine getirilen eleştirilere cevap verecek şekilde, Ruby on Rails' den ve benzeri platformlardan elde edilen geliştirme ve kullanım tecrübeleri ile, ASP.NET MVC altyapısı ile ortaya çıktı. ASP.NET MVC altyapısı MVC tasarım kalıbını kullanır. MVC tasarım kalıbının ortaya çıkışı 1978 yılına kadar uzanır. 

MVC (Model-View-Controller) kullanımı ile web uygulamasında ortaya çıkan kullanıcı etkileşimi aşağıdaki gibidir;
Kulllanıcı bir eylemde bulunur(Action, c# bu eylemi bir metodla temsil eder. Metodlarda bildiginiz üzere bir sınıf içinde olur. İşte bu sınıfa Controller denir.). Bu eyleme karşılık gelen OOP yaklaşımı ile modellenmiş bir bilgi var ise (Model) kullanıcıya bir HTML arayüzü (View) ile sunulur.

ASP.NET MVC;


  • Ticari yazılım geliştirirken uygulanan katmanlı mimari ile MVC arasında doğal bir uyum vardır.
  • Sunduğu bileşenlerin var olan hallerini kullandığınız gibi, ihtiyaç durumunda var olan davranışları değiştiren kendi sınıflarınızı yazmanıza olanak verir.
  • HTML ve HTTP üzerine geniş kontrol imkanı sunar. Html çıktısınız siz üretirsiniz. Basit ve standartlara uyumludur. JQuery,Bootstrap kullanmanızı destekler.(Visual Studio ASP.NET MVC proje şablonlarında varsayılan olarak bulunur.), 
  • Üretilen sayfalar viewstate içermez.
  • Test edilebilir kodlama yapmanıza olanak sağlar.Unit Testing desteği verir. UI test otomasyon araçlarıyla çalışabilmenize imkan sağlar.
  • Güçlü ve bir okadar da basit bir URL yönlendirme mekanizması vardır. Temiz ve basit URL üretmenizi sağlar. Üretilen URL fiziksel bir dizine karşılık gelmez.



ASP.NET platformu içinde MVC altyapısı da olacak şekilde aşağıdaki şekilde sunulmuştur.





 MVC altyapısı ile çalışırken konfigurasyon, güvenlik, ön bellekleme servislerinden yararlanırsınız. Bunlarda ASP.NET platformunun bir parçasıdır. Yani bu servisleri bir tek ASP.NET MVC altyapısı kullanmaz. Tüm ASP.NET teknoloji ailesi bunları kullanır.







ASP.NET MVC ile bu servislerin etkileşimi aşağıdaki şekilde gösterilmiştir.





Buraya kadar ASP.NET in bir platform olarak gelişim sürecine yer verdik. Bu süreç içinde MVC ' nin bir framework olarak ortaya çıkmasının nedenlerinden bahsettik.  Bu aşamadan sonra MVC tasarım kalıbı üzerine biraz daha eğilecek ve konuyu örneklerle açıklamaya çalışacagım. Boylelikle yazılım dünyamızda 
neden yeri olmalı, ihtiyac nedir daha iyi anlayabileceğiz.