Saraybosna notları

img_20190407_112246_283

“Welcome to the most beautiful country you have ever seen”

Dino Merlin’in burek şarkısı bu güzel ve iddialı söz ile başlıyor.

İstanbul –> Saraybosna

Balkanlarda hep görmek istediğim bir ülke olan Bosna Hersek’i sonunda görme imkanım oldu. Bu güzel şehri sizlere anlatıp tanıtmak istiyorum.

Tarihler 5 nisan, Atatürk Havalimanının son ticari uçuşlarının yapıldığı günde rotamız Bosna Hersek. Istanbul – Saraybosna yolculuk süremiz 1 saat 50 dk.

Saraybosna havalimanı küçük indiğiniz zaman yolunuzu bulmanız zor değil. Otobüs ile şehir merkezine gitmek için havalimanından çıkıp sağ tarafta bulunan durakta otobüs bekliyoruz.

Saraybosna

2 gece 3 gün sürecek seyahat için internet üzerinden pansiyon rezervasyonu yaptırdım. Başçarşı’nın yakınında bulunan şehir binasının yanında bulunan seçtiğim pansiyonda 2 gece konaklama imkanı buldum. Merkeze yakın çok sayıda kalacak yer mevcut, bütçenize uygun olanı bulup seçebilirsiniz.

Miljacka nehri kenarında, Avusturya-Macaristan esintileri bulunan binaların yanından geçerek yürüyüş yapabilirsiniz.

img_20190405_190055
Latin köprüsü (I.dünya savaşını başlatan Franz Ferdinand suikastinin gerçekleştiği köprü)

Kaldığım pansiyon Saraybosna şehir merkezi binasının, şehrin en gösterişli “landmark” olarak tabir edilen yapılarından biri, hemen yanında, Vijećnica bölgesinde bulunuyor.

Aynı zaman aynı bölgede tramvay istasyonu ve havalimanı otobüslerinin kalktığı durak bulunuyordu. Ulaşım ve önemli yerlere yakın bir lokasyon olan Vijećnica bölgesini kalacak yer seçenek göz önünde bulundurmanızı öneririm.

img_20190407_130104
Vijećnica (Sarajevo şehir binası) Avusturya-Macaristan dönemi en belirgin yapılarından birisi.

Nehir kenarından manzaralar ve tramvay.

img_20190407_081924
Tramvay ve nehir boyu sıralan binalar

Gelelim Başçarşı bölgesine ve şehrin simgesi olan Sebil’e. Şehrin merkezi ve buluşma noktası olarak adlandırabiliriz. Şehirde genel olarak buluşma ayarlayan insanların ilk adresi Başçarşı bölgesi ve Sebil

Sabah saatlerinde boş bulup çekim yaptığım Sebil ve Başçarşı. Akşamüstü ve akşam saatleri adım atacak yer bulunmuyor. Çeşmeden su içmenizi tavsiye ederim.

Sebil’in yakınlarında bulunan bakırcılar sokağına uğramadan şehirden ayrılmayın.

img_20190406_061244
Baščaršija sabah saat 6
img_20190407_081002
Sebilj

Osmanlı döneminin en önemli valilerinden biri olan Gazi Hüsrev bey’in adını taşıyan camii. Bosna sancağını yönettiği dönemde şehri kendi bölgesinin refah düzeyi en yüksek şehri yapmasıyla ünlenmiştir. Adil bir yönetici olup, vefat ettiği zaman mal varlığını; camii, türbe, medrese, vb kurumların inşası için bağışlayan önemli bir devlet adamıydı.

Gazi Hüsrev bey’in türbesi caminin avlusu içinde bulunmaktadır. Hemen yolun karşısında ise müze ve han yerleşkesi bulunmaktadır.

img_20190407_095216
Gazi hüsrev bey camii avlusu
img_20190407_101255
Gazi Hüsrev bey camii

 

Sabah saatlerinde dolaşırken sokağı boş bulup çekim yaptım. Normale akşamüstü ve akşam saatleri çarşının bu kısmı insandan geçilmiyor.

Sokağın bir ucu sebil’in bulunduğu meydana diğer tarafı ise Ferhadjia caddesine uzanıyor.

img_20190407_100842
Saraybosna çarşı sabah saatleri

Saraybosna’da yaptığım gece çekimlerinden biri. Avusturya-Macaristan döneminde, aşağıdaki ev, yetkililer tarafından yıkılmak istemiş ancak yapılan her teklife rağmen sahibini ikna edememişler. Bu yüzden evin ve restaurant’ın ismi Inat Kuca olarak anılmaya başlamış.

img_20190409_170520_689
Inat kuća

Şehirde Nazi işgalinden kurtuluşunu simgeleyen sönmeyen ateş bulunmaktadır. 6 nisan şehrin işgalden kurtuluş yıldönümü olduğu için anma töreni gerçekleşmiş.

img_20190407_085355
Eternal flame. 2.dünya savaşında şehrin kurtuluşunu simgeleyen ateş
img_20190407_111751_931
Maršala Tita street

Kuşbakışı şehir manzarası seyretmek istiyorsanız, şehre yukarıdan bakan Yellow bastion (sarı tabya)’ın yanında bulunan kafede Bosna kafa’sı içebilirsiniz.

pano_20190407_115737

Saraybosna Yemek tavsiyeleri

Şimdi ise en çok merak edilen konulardan birine değinelim, nerede, ne yenir ? 🙂 Belli başlı yemek yenilecek yerlere değinelim.

Şehirde yaşayan birinin paylaştığı aşağıda bulunan listeleri şöyle bırakıyorum.

Gittiğim ve beğendiğim çevapicileri paylaşarak seriye başlayalım. Birbirine rakip olan 2 çevapiciyi paylaşarak başlayalım.

Ćevabdžinica Petica Ferhatović

Her zaman kalabalık ve durmadan işleyen bir mekan. Servis hızlı ve güzel.

Ćevabdžinica Željo 2

Buregdžinica Bosna

Harika bir börekçi. Mutlaka uğramalısınız. Buregler az yağlı. Dolayısıyla mideye dokunmuyor. Rahatlıkla yiyebilirsiniz.

img_20190407_134901

Pekara nedir? Bizde de her yerde bulunan fırınlara pekara adı verilmiş. Çeşitli pastane ürünleri sunmaktalar.

Listede birçok pekaracı paylaşılmış. Ancak ben hemen başçarşı yakınında bulunan Pekara Edin adlı pastaneye uğradım.

Sarajevo brewery

Saraybosna’da bulunan bira fabrikasını tavsiye ederim. Hem restaurant hem bar olarak kullanılan bu güzel yerin içerisi aşağıda göründüğü gibi hoş bir havaya sahip

img_20190407_141823
Pivnica HS

Cafe Tito

Eski yugoslavya döneminden kalma eşyalar, hatıra fotoğraları vb antika parçaların barındığı cafe&bar hoş ve keyifli zaman geçirilebilecek bir yer.

img_20190405_182511_406

Saraybosna Ulaşım

Tramvay: tek kişi bilet 1.8 km. Sıklıkla tercih edilen bir ulaşım şekli olan tramvay’ı rahatça tercih edebilirsiniz. Tramvay’a binince, şoförden bilet alabilirsiniz.

Otobüs:  Havalimanından 10 numaralı otobüse binip şehir merkezine rahatlıkla ulaşabilirsiniz. Tek kişi bilet ücreti 5 km (mark) 5*3.3 = 15.5 tl civarına geliyor.Araç kiralamak isteyenler için ise havalimanında birçok seçenek mevcut bulunmaktadır. Otobüse binince, şoförden bilet alabilirsiniz.  havalimanından ulaşım için.

Taksi: Taksi kullanmak isterseniz; taksimetre 1km başına 1km olarak ücretlendirme yapıyor.

Tren: Tren istasyonu Avaz twist tower’ın (şehrin en belirgin yüksek yapısı) yanında bulunuyor. Mostar’a gitmek için tren kullandım. Detayları bir sonraki yazıda bulabilirsiniz.

Gözlemler

Saraybosna’da normal insanların yaşayışlarını anlayacak tanıyacak kadar uzun süre bulunmadım. Neticede 3 gün bulundum.

Yinede genel bir gözlem yapmak gerekirse; kahve her ülkede olduğu gibi çokça tüketiliyor. Merkezde bulunan yerel kahve dükkanları neredeyse çoğu zaman dolu. Örneğin, şehirde Starbucks’a rastlamadım. Yerel kahve dükkanlarının fazla bulunması ve tercih edilmesi güzel bir olay bana kalırsa.

img_20190407_172417

Diğere gördüğüm balkan ülkelerinde olduğu gibi sabahları kahvaltı olarak börek sıklıkla tercih ediliyor.

Şehirde olanlar bitenler, yerel insanların hayatlarını merak ediyorsanız, yukarıda referans gösterdiğim twitter hesabını takip edebilirsiniz. Günlük düzenli paylaşımlar yapıyorlar.

Müzik

Yugoslavya döneminde ünlenen, Saraybosna merkezli, Zabranjeno pušenje rock grubundan birkaç tane parça paylaşıp yazıyı sonlandırıyorum 🙂

Zabranjeno pušenje | Abid

Zabranjeno pušenje | Boško i Admira

Dino Merlin

Bosna Hersekli en meşhur sanatçı olan Dino Merlin için oluşturduğum müzik listesine buradan ulaşabilirsiniz

Dino merlin playlist

English version of this song

Bir sonraki yazımda Mostar ve çevresi hakkında detaylı bilgi vereceğim bir yazı yazacağım.

Microservice Architecture

Son dönemlerde sıklıkla bahsedilen microservice mimarisini araştırmayı ve öğrendiklerimi blog yazısı haline getirmeye niyetlendim. Microservice mimarisine geçmeden monolithic mimari hakkında kısaca bir özet geçelim.

Monolithic/Layered mimari aslında traditional SOA yaklaşımıdır. Standart web uygulamalarında, server side uygulama clientlardan gelen requestleri işleyip, veritabanından verileri çekip-güncelleyip sonrasında uygun html çıktısı olarak kullanıcılara göstermektedir. Tüm bu işlemler tek bir çatı altında toplanmıştır.

Tüm componentler tek bir yapı içerisinde birbirlerine bağlı durumdadırlar. Manageability (yönetim), maintenance (bakım) vb avantajlar nedeniyle tercih edilmektedir. Ancak büyüyen sistemler yönetimi zorlaştırmaktadır.

  • Uygulama büyüdükçe sistemin tekrar baştan ayağa kaldırılması uzun sürecektir.
  • Sistem içerisinde herhangi bir yapıyı tekrardan update etmek ve ettikten sonra tüm sistemi tekrardan deploy etmek zorunda kalabiliriz. Birbirine bağlı yapılar yeri geldiğinde  sorun çıkartabilir. Componentte yapılan değişim diğer componenti etkileyebilir.
  • Sistem içerisinde bulunan componentleri aynı dil ile geliştirilmek zorundayız.
  • Monolithic mimari olan sistemlerde scaling işlemi uygulama kopyaları oluşturularak, load balancer kullanılarak yapılır. Büyük uygulamalarda sıkıntı yaratacaktır. Küp yaklaşımında x ekseninde büyümeye tekabül eder. Birazdan inceleyeceğimiz microservice mimarisi y ekseninde büyümeye denktir.

  • Yeni teknolojileri veya dilleri sisteme adapte etmek zor olacaktır.

Bazı dezavantajlarını saydık. Avantajlarından birine değinecek olursak, componentler tek bir yapı içerisinde bulunduğundan birbirleri ile iletişimleri kolaydır. Nispeten küçük boyutlu ve karmaşıklığı az olan uygulamalarda tercih edilmelidir. Hızlı başlangıç için uygulamalara hız katar ancak uygulama boyutu arttıkça yönetilebilme sorunları ortaya çıkar.

Şimdi gelelim microservice mimarisinin nimetlerine ve getirdiği dezavantajlara. Martin fowler’ın sitesinde bulunan makalede detaylı bahsedilmektedir. Aslında microservis mimarisinin mantığı çok uzun zamandır biliniyor. Son dönemlerde popülaritesi artmıştır.

Microservis tabanlı uygulamalarda, componentler birbirinden ayrılmıştır ve ihtiyaç olduğu zaman birbirleri ile haberleşmektedirler. Microservis mimarisi mevcut uygulamanın boyutunu servislere bölüp azaltma amacındadır. Componentler birbirinden bağımsız tanımlanabilir. Yapılacak küçük bir değişim yüzünden tüm sistem tekrardan re-deploy edilmek zorunda değildir. Servislerin kendi aralarında haberleşmesi önem taşımaktadır.

Arayüz tamamen backend yapısından ayrılmıştır. Backend yapısı kendi içerisinde farklı servislere ve veritabanlarına ayrılmıştır. Bazı servisler NoSQL veritabanı kullanırken bazı servisler klasik veritabanı kullanabilir. Her servis üzerinde farklı yazılım ekibi çalışabileceği gibi her servis farklı bir dil kullanılarak yazılabilir. Servisler boyut olarak küçüktürler ve scale edilebilmeleri daha kolaydır.

Microservice mimarisine geçmeden önce uygulamamızın ihtiyacını karşılayıp karşılamadığını iyi anlamalıyız. Gereksiz yere kullanmaktan kaçınılmalıdır.

Microservice mimarisinin getirdiği dezavantajlara bakacak olursak;

  • Fazla zor bir case olmamasına rağmen geliştiriciler servisler arası mesajlaşma işini halletmelidir. Genelde servisler REST yolu ile iletişim kurarlar. Alternatif olarak async tabanlı AMQP protokolünü kullanabilirler.
  • Servisleri farklı yapılar ile geliştirme avantajı olsada yeri geldiği zaman karmaşıklığa yol açabilir.
  • Birbirinden bağımsız veritabanları kullanılan servislerde, verilerin birbirleri ile tutarsız olmaları sıkıntı yaratabilir. Servisler arasında kullanılan verilerin tutarlılığını sağlamak için Event-driven mimari kullanılabilir. Veritabanında bulunan veri değiştiği zaman servis olay mesajı olarak bilgilendirme yapar. Buna göre diğer servisler verilerini günceller.
  • Deployment süreci zorlaşabilir.

Uygulamanın boyutu küçükse ve fazla logic yoksa monolithic mimari tercih edilmelidir.

Kaynakça

DIP – IoC – DI ve IoC container kavramları

Daha önce SOLID prensiplerini anlatırken bahsettiğimiz Dependency Inversion Principle yani bağımlılıkların tersine çevrilmesi prensibinin nasıl gerçek örnekler üzerine implement edileceğinden bahsedeceğim.  Bu prensip altında kullanılan ve birbirleri ile karıştırılan konuların üzerinden geçeceğim.

İyi bir yazılım sistemi geliştirirken kullandığımız elemanlar birbirlerine az bağımlı (loosely coupled) olmalıdır. OOP ile geliştirdiğimiz nesneler esnek olmalıdır ve birbirlerine az bağlı olup değişimlerden az etkilenmelidir. Sistem reusable olmalıdır, kodlar ise encapsulated olacak şekilde geliştirilmelidir. Herhangi bir component diğer  bir component’in ne yaptığı ile ilgilenmemelidir.

En Kullanışlı 2 yöntem abstraction ve interface yapıları ile inşa etmektir. Eğer componentler ileride değişikliğe uğrayacak ise onları concrete tanımlamak yerine, interface yardımı ile oluşturmalıyız.

Aşağıdaki resme bakarak genel kavramlar daha iyi netleşmektedir.

image2

Dependency Inversion Principle (DIP): Yazılım geliştirirken kullanılan SOLID prensiplerinden biridir. Bir sistemin nesnelerinin birbirlerine olan bağımlılıkların az olması için yapılması gerekenleri anlatır. Ancak nasıl gerçek uygulamalar üzerinde uygulanacağını (problem çözümünü) anlatmaz. Bize tanımlama yapar.

Yüksek seviyeli componentler tanımlama yapar ve alt seviyeli componentler onlara bağlı olur. Yani üst componentler alt componentlere bağlı olmaz. Böylece tam tersi olur, bağımlılıklar ters çevrilerek sistem esnek olur. Hem üst seviye, hem de alt seviyeli componentler abstractionlara (soyutlamalara) bağlı olur.

“Abstractions should not depend on details, Details should depend on abstractions.”

Özet olarak DIP prensibi bize sistemin loosely coupled, bağımsız, modüler ve test edilebilir olması gerektiğini söyler.


Inversion of Control (IoC): DIP prensibini uygulayan tasarım şablonudur. Herhangi bir yapıyı yöneteni invert etmektedir. Sınıf veya sistem içerisindeki herhangi bir modülün kullanacağı bağımlılıkları dışarıdan üretip kullanması gerektiğini söyler. Soyutlama yapmamızı sağlar.

Eğer alt seviyeden bağımsız bir üst seviye component oluşturmak istiyorsak, alt seviye componentlerin nesne oluşturmaması için kontrolü invert edip nesne oluşturma işini üst seviye componentler tarafından yapılmasını sağlamalıyız.

IoC yapmak için 3 yol  bulunur. (Yukarıda olan şemada 2 yol bulunuyor.)

  • Interface inversion  (Interfaceler invert ediliyor.)
  • Flow inversion (Akışı invert et)
  • Dependency creation & binding (kendi içinde 3’e ayrılır. en çok kullanılan yöntem DI)

Dependency Injection (DI): IoC pattern’ı uygulamak için yapılmış implementasyondur. Bağımlı nesneleri oluşturma ve bağlama işini sınıfın içinde değil dışarıda yapmaktadır.

Normal şartlarda herhangi bir sınıfın kullanacağı sınıflar, o sınıfın içerisinde tanımlanır. Böylece sınıf, oluşturulan nesnelere bağımlı olur (Tightly coupled). Dependency injection kullanarak bu bağımlı nesneler dışarıda oluşturulur. 3 tane yolu vardır. Kendimiz DI yönetimi oluşturabileceğimiz gibi hazır olarak kullanılmaya hazır IoC framework yapılarından birini kullanarakta yapabiliriz.

  • Constructor Injection: Sık kullanılan bir DI yoludur. Dışarıda oluşturulan bağımlılıkları, aktarılmak istenen sınıfa constructor üzerinden göndeririz. Repository sınıfı içerisinde sadece Save() metodu olan boş bir sınıftır ve IRepository interfaceden türetilmiştir. Main içerisinde oluşturulan repository nesnesi, transaction nesnesine constructor ile enjekte ediliyor. Dbrepository yerine farklı bir repository bağlasak bile transaction sınıfı bağımlı olmadığından sıkıntı olmayacaktır. Çünkü transaction sınıfı içerisinde repository interface ile tanımlanmıştır.

dip1

dip2

  • Setter Injection: Sınıf içerisinde bağımlı sınıfı örneklemek için kullanılacak bir değişken tanımlanır. O değişken set edilerek bağımlılık enjekte edilir. Transaction içerisinde tanımlanmış Repository değişkeni main içerisinde nesne tanımlanırken set ediliyor.

dip3

dip4

  • Interface Injection: Fazla kullanılan bir yol değildir. Inteface içinde metod oluşturulur ve bağımlılık o metod ile aktarılır.

Ioc Container: Dependency Injection yapmak için kullanılan frameworklere denir. Nesne oluşturmasını denetler ve nesnelerin yaşam döngülerini kontrol eder. Sistem çalıştığı zaman ihtiyaç olan bağımlı nesneleri doğru şekilde üretir. C# ile kullanılan IoC containerlar aşağıda gösterilmiştir.

Kaynakça

Observer Design Pattern

Behavioral (davranışsal) tasarım kalıplardan olan observer pattern sık kullanılır. One to many ilişkili birden fazla nesneden oluşur. Bir nesne değiştiği zaman, ona bağlı diğer nesnelerde otomatik olarak değişmektedir. Olay (event) bazlı değişimler olmaktadır.

Aslında observer pattern c#’da bulunan event yapısı ile aynıdır.

Subject: Ana nesnedir. Bu nesne içerisinde diğer nesnelerin içinde bulunduğu liste vardır. Yani diğer nesneler(observers) subject’e bağlıdır. Birden fazla observer tek bir subject’e bağlanabilir. Notify() metodu ile observerların içerisinde bulunan update() metodunu çağırır. Attach() metodu ile nesne bağlarız. Detach() metodu ile nesneleri ayırma işlemini yaparız.

Observer: Subject’e bağlıdır. Ana nesnede değişim olduğu zaman observer içerisinde bulunan update() metodu subject tarafından çağrılır. Böylece her observerler meydana gelen değişimden etkilenir.

Yukarıda bahsettiğim subject ve observer nesnelerini metodları aşağıdaki uml şeması ve sequence diyagramı ile gösterilmiştir. Notify() ile mevcut tüm observer nesnelerinin update() metodları çağrılmaktadır. Böylece olan değişimlerden observerlar etkilenir. Concreteobserver nesnesinde, subject tarafından çağrılan update() metodu içerisinde mevcut durum güncellenir. Concretesubject ise değişim olduğu zaman observerlara bildirim yollar.

 

observeruml
uml şeması

sequence diyagram
sequence diyagram

Örnekler: Observer pattern çalışma mantığını örnekler ile anlatalım.

  • Verilerin 3 farklı sunum şekli tanımlanmıştır. Bunlar observer, veri kaynağı ise subject olarak tanımlanmıştır. Subject üzerinde yapılan herhangi bir değişiklik observerlar üzerinde uygulanır. Observer nesneleri veriyi aynı yerden alırlar ancak birbirlerinden haberleri yoktur. Birden fazla observer bulunabilir.

observer-spreadsheet-example

  • Bir diğer örnekte sorular sorulup kullanıcıların cevapladığı yaygın platform quora üzerinden olsun. Sorulan soru subject olsun. Bu soruyu takip eden 13 kişi olsun. Takipçiler observer nesneleri olacaktır. Mevcut soruya yeni bir cevap yazıldığı zaman soruyu takip eden herkes bildirim almaktadır.
  • MVC (model view controller) mimarisi observer pattern için bir örnektir. Modelin(subject), viewlar(observers) ile ayrışmasını sağlar. Model üzerinde herhangi bir değişim olduğu zaman tüm viewlar etkilenecektir.
  • Event management (olay yönetimi) yapılırken kullanılır.

Kısaca tanıtım yaptıktan sonra kod kısmına geçelim. Github üzerinden koda erişebilirsiniz.

Örnekte ürün market ilişkisi observer pattern ile gösteriliyor. Ürünler subject olarak, marketler observer olarak tanımlanmıştır. Ürünlerin fiyatları değiştiği zaman tüm marketler bu değişimden haberdar olacaktır.

Ürünler için abstract olarak Product sınıfı tanımlanmıştır. Bu sınıftan yeni ürünler yani subjectler türetilecektir. Attach() metodu içerisinde shops listesine marketler eklenmektedir. Yani fiyat değiştiği zaman güncellenecek olan observerlar burada bağlanıyor. Detach() metodu ile tam tersi olarak listeden marketler çıkarılmaktadır. Fiyat ve ürün ismi olarak 2 değişken döndürülmektedir.

abstractsubject

  ProductA sınıfı bu abstract sınıftan türetilmiştir. Aynı şekilde birden fazla ürün yani subject oluşturup onlara farklı farklı observerlar bağlayabiliriz.

concretesubject

Concrete observer sınıfı ile subjectlere bağlanacak nesneler oluşuyor. Bu sınıf içerisinde Update() metodu içeren bir interfaceden kalıtım almaktadır. Subject içerisinde bulunan Notify() metodu içerisinde observer içerisindeki update metodu çağrılmaktadır. Böylece ne kadar nesne üretilmiştir ise hepsi değişimden haberdar olacaktır.

observer

Programı çalıştıran kod aşağıda gösterilmiştir. Önce observer ve subject nesnelerini oluşturduk. Ardından subject nesnelerine observerları attach() metodu ile bağladık. Ardından fiyat değişimleri yapınca her bir observer nesnesinin update() metodu çağrılmaktadır.

programcode

Ekran çıktısı

output

Kaynakça

Node.Js – Middleware

Node.Js Giriş yazısından sonra middleware kavramı ile yazılarıma devam ediyorum..

Middleware kavramının tam bir tanımı olmamakla birlikte genel olarak; geliştirici ile sistem arasında bulunan katmandır. Sistem derken ya işletim sistemi ya da Node altyapısı olan sistemi kasteder.
Daha spesifik olarak middleware katmanı kendisini uygulama ile sistem arasında iletişim katmanı olarak atamaktadır.

Middleware katmanı olmadan uygulama geliştirirsek tüm request işlemi tek ve uzun bir request handler ile yönetilecektir. Middleware yapısı sayesinde request handler parçalara bölünüp, her parçada farklı bir iş yapmamızı sağlar. Middleware kullanarak yapabileceklerimiz;authorization, proxies, routers, cookie ve session yönetimi. Örneğin ilk middleware yapısı log işlemi olsun ve tüm istekler console üzerinden görüntülensin. Bir sonraki middleware olarak authentication olsun ve yetkisi olmayan kullanıcılar daha sonraki middleware katmanına geçemesin.

nodemiddleware

Normal node yapısında middleware yapısı yukarıdaki resimdeki gibi işlemektedir. Client istek yapar. Node http server bu isteği yazdığımız handler function yapısına iletir. Handler içerisinde istek işlenir ve http server’a tekrar yollanır.

Connect ve Express frameworkleri kullanarak işlemlerimizi kısaltmaktayız. Bu yazıda express frameworkten fazla bahsetmeden middleware yapısını anlatmak istiyorum. İkisi arasındaki farka değinecek olursak Connect framework ile sadece middleware işlemine odaklanabiliriz. Express framework kullanırsak daha kapsamlı işler yaparız (routing, view rendering vs). Express, connect framework ile uyumludur. Express kullanırken middleware fonksiyonlarını kendimiz yazabiliriz veya hazırda bulunan geliştiriciler tarafından yazılımış açık kaynaklı module yapılarını kullanabiliriz. Aşağıdaki yapı express middleware yapısını göstermektedir.

expressmiddleware

Node http server üzerinden giden istekler stack yapısında toplanır. Stack yapısı içerisinde istek middleware fonksiyonlarını teker teker işleyip sonunda respond olarak http server’a kullanıcı isteğinin cevabını döndürür. Stack aşamasında middleware yapıları işlenirken herhangi bir hata oluştuğu durumda işlem sırası kesilip hata middleware yapısına geçilmektedir. Kısaca özetlersek express frameworkte gelen istek stack yapısı üzerinden yukarıdan aşağıya doğru tüm middleware işlemlerinden geçer.

 

Middleware fonksiyonları 3 parametre almaktadır. Request ve response sürekli bulunmalıdır. Bunlar: function logger(request,response, next). Hata middleware yapısı ise 4 parametre alır. err, request, response, next 

Örnek verecek olursak; logger yaparken, console.log ile basit bir logger yapısı yaparız. Eğer logger işlemini gerçekleştirmek için hazırlanmış “morgan” adı verilen module yapısını kullanırsak işlemimizi kısaltırız. Sonuçta tekerleği yeniden icat etmemize gerek yok hazır geliştirilmiş modülleri kullanıp yapacağımız işe odaklanmak daha mantıklıdır.

Express.js, middleware yapısını kendi sitesinde basitçe anlatmış. Kısaca özetleyecek olursak. Önceden yüklenmiş(npm install express –save) express modulünü ekliyor ve app değişkenine express uygulamasını tanımlıyor. Mylogger ile basitçe log yapısı oluşturup next() metodu ile bir sonraki yapıyı çağırıyor. app.use(myLogger) ile stack yapısına ekleme işlemi yapılıyor. Ardından routing işlemi yapılarak “/” yani açılışta gösterilecek ilk ekrana “hello world” yazdırıyor.

ekran-alintisi

ekran-alintisi2

Middleware yapısı hakkında bilgi vermeye çalıştım. Nodejs giriş yazısında kaynakçaya eklediğim linklerde daha detaylı bilgi bulabilirsiniz.

Bu makalede aslında express’e kısaca giriş yapmış olduk. Bir sonraki yazımda express framework hakkında yazacağım. Node.Js kullanarak yapacağım örnekleri siteye eklemeyi düşünüyorum.

Node.Js Giriş

Node.Js ile ilgili yazı serisi yazmaya başlıyorum. Uzun zamandır yazmayı düşündüğüm bir konu hakkında kendimi geliştirirken buradan paylaşmanın güzel olacağını düşündüm.

Kısaca tanımlayacak olursak; Javascript üzerinde server-side uygulamalar yazmamızı sağlayan bir framework’dür.

Kendi sitesinde kullandığı tanım;

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

Sitesinde ve birçok kaynakta nasıl kurulduğu ve npm ile paket yönetimi nasıl yapılır detaylı anlatılmaktadır. Uzunca nasıl kurulduğu hakkında yazı yazmaktan ziyade Node.Js’nin sağladığı faydalardan başlayalım.

Chrome web browserlarının da üzerinde çalıştığı V8 engine yapısını kullanmaktadır. V8 kullanması hız ve performans artışı sağlamaktadır. Tanımda belirtildiği gibi I/O ve network işlemlerini non-blocking olarak çalıştırmaktadır. Yani herhangi bir işlemin bitmesini beklemeden diğer event ile ilgili işlem başlamaktadır. Örneğin veritabanı sorgusunun sonucu beklemeden başka bir işleme geçilmektedir. Böylece performans artışı önemli bir biçimde görmülmektedir. Real-time ( gerçek zamanlı ) uygulamalar yaparken tüm kullanıcılara aynı anda bilgi akışı sağlanmaktadır.

threading_node

Resimde görüldüğü gibi clientlar tarafından request yapılmaktadır. Event loop yapısı içerisinde istekleri değerlendirip işlemektedir. Non-blocking yapısı sayesinde herhangi bir bekleme olmamaktadır.

Başta Linkedin ve paypal olmak üzere önemli firmalar tarafından kullanılmaktadır.

1 – Asynchronous(Asenktron) ve Event-driven(Olay tabanlı): browser

Node server-side ve client side için event driven ve asenkron bir yapı sunmaktadır. I/O işlemleri yaparken non-blocking yapısı vardır.

Async I/O: Mevcut işlem bitmeden diğer yapılmak istenilen işlemlerin halledilmesine olanak sağlar.

Browser üzerinde non-blocking yapı aşağıda gösterilmiştir. Belirtilen json dosyasından verileri okuma işlemi devam ederken farklı bir request yapabilmekteyiz. I/O işlemi event loop dışında gerçekleşmektedir. Veri okuma işlemi bitince callback fonksiyonu çağrılıp console.log ile veriler ekrana basılıyor.

nonblockingbrowser

Browser daha esnek bir yapıya kavuşuyor. Pek çok istek aynı anda işlenebiliyor.

2 – Asynchronous(Asenktron) ve Event-driven(Olay tabanlı): server

var result = query(“SELECT * FROM table”) syntax’a dikkat etmden bir db sorgusunu temsilen yazalım. Bu işlemi normal şekilde tanımlarsak, tüm veriler okunmadan diğer işlemler dikkate alınmayacaktır. Blocking I/O yapısı vardır.

Bu sorunu çözmek için multithread yapı kullanırsak, bir süre sonra multihreadleri kontrol etmek zorlaşabilir. (örn Apache). Thread sayısı arttıkça context switch işlemi artacaktır. Dolayısıyla ciddi bir performans kaybı yaşanacaktır.

Farklı bir çözüm olarak non-blocking yapı kullanıp aynı anda birçok request talebi işlersek daha esnek bir yapı oluşacaktır. (örn NGINX) Tek thread kullanmasına rağmen apache’ye göre daha hızlı şekilde istekleri değerlendirir.

nginx-apache-reqs-sec

Node içerisinde, I/O işlemleri her zaman event loop dışında gerçekleşmektedir. Server’ın esnek ve kullanışlı olmasını sağlar. (örnek nginx (3x daha hızlı) )

3 – DIRTy uygulamalar ( data intensive real time ) 

Server tarafında gerçekleşen değişikliklerin client tarafında sayfa yenilemeden anlık olarak gösteren uygulamalardır. Birden fazla istek aynı anda gerçekleştirilebilir. Node DIRTy uygulamaları desteklemektedir. Browser ve server arasında tutarlılık sağlanır.

İlk node.js yazısını kısa bir hello world örneği ile bitirelim. server.js adında dosya oluşturup aşağıdaki kodları yazalım.

Cmd ekranında ilgili klasöre gelip. “node server.js” yazıp serverı çalıştırırız.

Ardından browser üzerinden localhost:3000 adresini açarsak ekranda hello world yazısı gözükecektir.

Node.Js’e kısaca tanıtmış olduk. Daha detaylı öğrenmek isteyenler kaynakçada bulunan linklere bakabilirler. Özellikle kitapları ücretsiz olarak pdf biçiminde bulabiliyoruz.

Kaynakça

C# / Async programlama ve Thread Kavramı 1

Async programlama bölümüne geçmeden Thread ve multithread yapılarından bahsetmek istiyorum. Thread yapısından bahsetmeye başlayarak yazıya başlayalım. Multithreading, thread scheduler tarafından yönetilir. CLR tarafından OS’ye delegate edilen bir fonksiyondur. Scheduler, her thread yapısının makul bir execution süresi içerisinde tamamlanacağını garanti eder. Bekleyen veya blocklanan threadler CPU zamanını harcamazlar.

Tek işlemcili bilgisayarlarda, thread scheduler hazırda çalışmak için bekleyen thread yapılarını belirli scheduling algoritmalarına göre işleme almaktadır. Her seferinde tek thread çalışmaktadır. Çok işlemcili bilgisayarlarda ise, birden fazla thread aynı anda çalışabilmektedir. Bu sayede scheduling algoritmaları ile daha efektif işlem süreleri içerisinde işlemleri tamamlamaktayız.

Thread vs Process

Thread yapıları işletim sistemi işlemlerine benzemektedir. OS içerisinde işlemler birbirine paralel olarak çalışmaktadır. Thread yapısında ise, threadler bir process içerisinde birbirlerine paralel olarak çalışmaktadırlar. İşlemler birbirlerine tamamen izoledir. Threadler birbirlerine tamamen izole değillerdir. Aynı hafızayı paylaşırlar bundan dolayı birlikte çalışan threadler arasından veriler rahatça paylaşılmaktadır.

process-thread

Thread ve Task yapısının kullanım örneklerine geçmeden önce bazı kavramları netleştirelim. Sıklıkla kullanılan bir örnek üzerinden anlatacağım. Restaurantta yumurta ve tost siparişi geldiğini düşünelim.

  • Synchronous: Önce yumurtayı pişir. Ardından tostu hazırla.

 

singlethreaded
sync single thread

 

multithreaded
sync multithread
  • Asynchronous – single threaded: Yumurtayı mutfakta pişirmeye başla bekle. Ardından tostu makinede hazırlamaya başla ve bekle. Bekleme esnasında yeni sipariş gelirse al. Pişirme süreleri bitince müşterilere servis yap.

 

async single thread
async single thread

 

  • Asynchronous –  multithreaded: 2 yeni aşçı işe alalım. Biri sadece yumurta pişirsin. Diğeri ise sadece tost hazırlama işini halletsin. Mutfakta malzeme kullanırken birbirleri çakışmalarını engellememiz lazım. Ayrıca her ikisinede maaş ödemek durumundayız.

 

async multithread
async multithread

 

Async programlama ile sistemin esnekliği ön plana çıkar. Örneğin; uzun bir hesaplama yapılacağı zaman async programlama ile yapılırsa arka plan’da çalışan thread içerisinde bu işlem halledilir. Sistem ön planda hala esnek durumda kalacaktır.

Paralel programlama ise farklıdır. Her ne kadara bu yazıda bahsetmeyecek olsak bile bahsetmekte fayda olduğunu düşünüyorum.  Paralel programlama ile sistemin CPU performansı gibi özellikler ön plandadır ve tüm çalışan thread yapıları tek bir işlemi yapmak için çalışır. Belirli bir task’ı birden fazla thread kullanacak hızlıca tamamlamaktır. Task’ı tamamlamak için birden fazla kaynak kullanmak olarak düşünebiliriz.

Thread

Teorik girişten sonra artık console application üzerinde threadler ile ilgili işlemlere başlayalım. Aşağıdaki örnekte WriteY() adlı metod thread tanımlanarak çağrılmıştır. Console uygulamasının çalıştığı main metodu içerisinde i  değişkeni 0’dan 100′ e kadar giden for içerisinde “x” ekrana yazılacak. WriteY içinde ise aynı şekilde for döngüsü içerisinde y yazılacaktır.

thread01

Program çıktısı her seferinde farklı olacaktır. Çünkü thread schedular tarafından düzenlenen çalışma sırası her seferinde farklı çalışma öncelikleri ile threadleri tamamlayacaktır.

thread01output thread01output2

Lambda ifadeler kullanarak daha kısa thread tanımları da yapabiliriz.

thread01lambda

Threadler ile çağırdığımız metodlara parametrede gönderebiliyoruz.

thread02

Thread.CurrentThread.Name özelliği ile çalışan thread’in ismini öğrenebiliriz. Thread ismi ayarlamak için threadName.name = “threadismi” şeklinde tanımlama yaparız.

Oluşturduğum tüm threadler default olarak “foreground (ön plan)” şeklinde tanımlanır. Uygulama tüm foreground threadler tamamlanınca biter. Thread özelliği “background (arka plan)”  olarak değiştirilirse, background thread devam etse bile uygulama bitebilir. Bu durumda background thread aniden kesilmiş olacaktır. threadName.Isbackground = true biçiminde tanımlama yapılarak özellik değiştirilebilir. threadName.Join() metodunu çağırarak tüm threadlerin bitmesini bekleyip programı öyle sonlandırabiliriz.

Thread.Sleep (TimeSpan.FromHours (1));  // 1 saat bekle

Thread.Sleep (5000);                     // 5 saniye bekle

Threadlerin Sleep veya Join durumlarında beklemeleri esnasında thread blocklu durumdadır ve CPU kaynaklarını harcamaz.

Aşağıdaki örnekte _field değişkeni ThreadStatic olarak tanımlanmıştır. Bu tanımlama ile _field değişkeni her thread için farklı olacaktır. Şöyle düşünelim ilk thread içerisinde  1’den 10’a kadar döngü içerisinde artıp ekrana çıktı olarak gösterilecektir. Diğer thread başladığı zaman o thread için _field değeri 0 olduğundan 0’dan 10’a kadar tekrardan artış olacaktır. ThreadStatic özelliği eklenmemiş olsa diğer thread için artış 10’dan başlayıp 20’ye kadar olacaktı.

thread022

Ekran görüntüsü

thread021

Thread pooling yapısı ile performans açısından thread yapılarını daha verimli kullanabiliriz.

Tasks

Async programlama ile daha sıklıkla kullanılan Task yapısı thread yapısına göre üst seviyede. Task yapısını kullanarak daha gelişmiş işlemler yapabiliriz. Thread pooling yapısını otomatik olarak kullanıp birbiri ardına eklenebilecek olan işlemleri daha iyi organize etmektedir.

Aşağıdaki yapıda tasks adında türü task olan bir dizi oluşturduk. Bu dizi 3 task değeri alacaktır. Task tanımlamalarımızı yaptıktan sonra Task.WaitAll(tasks) metodu ile tüm taskların çalışıp biteceğini garanti ettik. Aynı thread yapısında bulunan join() metodu gibi

task01

task011

Bu yazıda thread kavramına giriş yaptık. Ardından Task kavramına kısaca değindik. Diğer yazılarımda async ve await ile yapılan async programlama gibi kavramları anlatmaya devam edeceğim. Daha detaylı bilgi ve işlemler için çeşitli kaynaklara bakabilirsiniz.

Önemli linkler

C# / MongoDb – MapReduce

Herkese merhaba. Bugün yazacağım makalede MongoDb ile MapReduce işlemleri yapacağız. Öncelikle MapReduce yapısı hakkında kısaca bir giriş bölümü yazacağım.

MapReduce dağıtık mimari üzerinde büyük verilerin kısa zamanda analiz edilebilmesini sağlayan bir sistemdir. Verileri analiz edip onlardan aggregate sonuçlar üretmek için kullanılır. Map fonksiyonu ile belirtilen key/value değerlerine göre veriler toplanır. Ardından Reduce fonksiyonu ile toplanan veriler aggregate sonuçlara çevrilir.

  • Map fonksiyonunu SQL select sorgusu olarak düşünebiliriz.
  • Reduce fonksiyonunu ise; count, having, avg gibi SQL sorguları olarak düşünebiliriz.

Hesaplama map fonksiyonu içerisinde key/value değerleri alır ve reduce işlemi sonrasında key/value değerlerine göre bir çıktı üretir. Her iki fonksiyonda kullanıcı tarafından yazılmaktadır.

Aşağıda gösterilen örnekte her kelimeden kaç adet bulunduğu hesaplanıyor. Öncelikle değerler 3 gruba ayrılıyor. Ardından mapping kısmında her grupta bulunan kelimeler sayılıyor. Sonrasında her grupta aynı olan kelimeler bir bölümde toplanıyor. Reduce aşamasına geçildiği zaman ise her bölümde toplanan kelimeler sayılıyor ve en son değerimiz ekrana çıkarılıyor. Giriş değerimizin büyük boyutta olduğunu düşünelim. Böylece istenilen sorgu map reduce ile kolayca elde edilmektedir. Map reduce ile ilgiyi geniş bilgi internette fazlasıyla mevcuttur. Detaylı bilgi için; research.google, wikipedia

map-reduce-flow

Örnek: Bu yazıda göstereceğim map reduce işlemi daha önce üzerinde örnekler yaptığım restaurants collection üzerinde olacaktır. Collectionda bulunan her documentta restaurantın bulunduğu semt adı bulunmaktadır. Map fonksiyonu ile semt değerine göre gruplama yapılacak. Ardından Reduce fonksiyonu ile her semt değeri için mevcut olan restaurant değerleri toplanıp çıkış değeri olacak gösterilecektir. Ekstra olarak restaurantları yemek türüne göre filtreleyip hangi yemek tipinden nerede kaç restaurant var görebiliriz.

  • Veritabanı için gerekli bağlantılar

1

  • MapReduce işlemleri için gerekli javascript fonksiyonlarını yazalım. MongoDb’de MapReduce işlemini uygulamak için fonksiyonlar javascript formatında yazılmalıdır. Map fonksiyonu ile borough (ilçe) değeri anahtar olarak belirtilmiştir. Value değeri olarak 1 yani her value değeri için o değer üzerine +1 eklenecektir. Reduce fonksiyonu ile values dizisine biriken değerler her key değeri için toplanıyor. Finalize fonksiyonu içerisinde toplanan değerler integer olarak ekrana döndürülüyor. Finalize fonksiyonu reduce işleminden sonra yapılacak olan düzenlemelerin uygulandığı fonksiyondur.

 

2

  • Restaurant tipine göre filtreleme yapmak istersek;

3

  • Öncelikle MapReduceOptions ile gerekli ayarları yapıyoruz. Giriş değeri restaurant sınıfı, çıkış değeri ise BsonDocument olarak belirtilmiştir. MapReduce metodunda tanımlarını yaptığımız fonksiyonlar (map-reduce) ile options parametresine belirttiğimiz ayar değerlerini yazıyoruz. Ardından tüm sonuçları await results.ToListAsync() ile docs değişkenine atıyoruz. Bütün bu işlemleri yaptığımız metod async değer döndürmelidir. Çünkü MongoDb yeni sürümü ile async/await olarak sorguları çekmekteyiz. Foreach kısmında ekrana yazma işlemleri yapılmaktadır.

4

  • Filtresiz ekran çıktısı. Sonuçta görüldüğü gibi 25.360 değer mevcuttur. MapReduce işlemi ile tüm verileri tarayıp az sürede sorgu gerçekleşmektedir.

restaurantoutput

  • Filtre kullanılarak yapılan sorgu sonucu oluşan ekran çıktısı. Restaurant yemek tipi “irish” olan restaurantları sorguluyor.

restaurantoutputfilter

Mevcut veriler için MapReduce işlemini gerçekleştirdik. Peki yeni veriler eklendiği zaman tekrar tüm veriler aynı işlemden geçirilmeli mi? Geçirilirse büyük veriler için maliyet kaybı olacaktır. Bu durumlar için Incremental MapReduce uygulanır. Sadece yeni eklenen verilere işlem uygulamak için, örneğin belli bir tarihten sonraki eklenen değerleri almak için bir sorgu yazarız. Böylece sadece yeni veriler MapReduce işlemine tabi olur. İşlem bitince eski sonuçlara yeni sonuçlar eklenir.

İngilizce versiyonu

Kaynaklar

MapReduce Doc

Asp.NET Web API – MongoDB

Bir süredir ara verdiğim MongoDB serisine devam ediyorum. Bu yazıda Asp.NET Web API framework ile yapılan projede MongoDB veritabanından çekilmiş olan verileri REST yapısında tüm kullanıcılara göstereceğiz. Ardından bir diğer yazıda JSON biçiminde dönen verileri sorgu ile web api’den çekip kullanacağız. Veri seti olarak MongoDB sitesi üzerinde örneklerde kullanılmak üzere paylaşılan restaurants veri setini kullanacağım. Bu linkten indirilebilir.image001

Uygulamayı local üzerinde çalıştıracağımız için cmd ekranı üzerinden mongod komutu yazılarak, server başlatılmalıdır. Eğer kurulum yapmadıysanız MongoDB giriş makelesinde kuruluş için gerekli linkler mevcuttur. İlk başta temel olarak verilerin ekranda gösterilmesi, belirli bir restaurant id değerine göre gözükmesi, güncellenmesi ve silinmesi gibi REST’in temel işlemlerini ekleyeceğim.

Öncelikle visual studio üzerinden web api projesi açıyoruz ve nuget paketlerinden mongodb offical driver’ı yükleriz. Proje yapısı aşağıdaki gibidir.  DAL yani veri ile direk temas yapacak olan kısım ayrı bir sınıf kütüphanesi olarak eklenecektir. Bu kütüphanede veriler ile yapılacak işlemler için Generic Repository ve Unit of Work patternleri uygulayarak daha güzel ve esnek bir yapı oluşturuyoruz. Oluşturulan bu esnek yapı sayesinde uygulamanın test edilebilirliği ve yönetilebilmesi kolaylaşmaktadır. Ana proje bölümünde şimdilik sadece resturantcontroller sınıfı içerisinde işlemler yapılmaktadır. Dependency Injection, authorize ve log işlemleri yapmak istersek projeye ilaveler ekleriz.

Detaylı olarak bu yapıyı bu yazıda anlatmayacağım. Bu linkte bulunan yazıda generic repository ve unit of work yapısı hakkında detaylı bilgi mevcuttur.

1

MongoDb sitesi üzerinden indirdiğimiz örnek veri setinin yapısı aşağıdaki gibidir. Bu veri setindeki yapıya uygun olarak model sınıflarımızı oluşturacağız.

2

Temel model sınıfı olan restaurant aşağıdaki gibi tanımlanmıştır. Address sınıfı restaurant sınıfı içerisine yerleştirilmiştir. Address için ayrı bir sınıf oluşturup restaurant sınıfı içerisinden çağırmaktayız. Grades bölümünde sınıflar liste biçiminde eklenmektedir. Bu sınıfı oluşturup aynı Address sınıfını eklediğimiz gibi restaurant içerisine eklemekteyiz.

35

4

Öncelikle repository sınıfı oluşturuyoruz. REST mimarisinde bulunan GET, GET by id, POST, PUT ve DELETE gibi işlemler controller içinde tanımlanır. Controller içerisinde olan REST işlemlerinin uygulayacağı işlemler repository sınıfında tanımlanmıştır. Bu tanımlanan işlemler unit of work sınıfı aracılığı ile çağrılacaktır. Aşağıda repository sınıfının tanımlanması ve constructor içerisinde yapılan tanımlamaları gösterilmektedir. Sınıf generic yapıdadır. T ile belirtilen değişkene, repository sınıfı çağrılırken data modelimiz olan Restaurant sınıfını atayacağız. Repository sınıfını UnitOfWork sınıfımız içinde örnekleyeceğiz.

6

Aşağıdaki resimde repository sınıfında tanımlanmış olan metotlar gösterilmiştir. Bu metotlar controller kısmında gerekli işlemleri yapmak için çağrılacaktır.

7

UnitOfWork sınıfı aşağıdaki gibi oluşmaktadır. Constructor içerisinde veritabanına bağlanmak için gerekli işlemler yapılıyor. Oluşturduğumuz repository sınıfı için değişken tanımlanmıştır. Bu değişken repository sınıfını döndürüyor. Eğer örneklenmemiş yani değeri boş ise new ile örnekleniyor. Eğer daha önceden örneklenmesi yapılmış ise mevcut değer tekrar dönüyor. Controller içinden GET metodunu döndürmek istersek; unitofwork.Restaurant.GetAll() yazmamız gerekiyor.

8

Controller sınıfında constructor içerisinde unitofwork örneklenmiştir. Controller sınıfında REST yapısında kullanılan işlemler tanımlanmıştır. Tüm verilerin gösterilmesi için çağrılan GETfonksiyonu ve sadece belirli ObjectId değerine göre sadece tek bir değer çekmemiz için çağrılan diğer GET fonksiyonuda gösterilmiştir.

11

Aşağıda veri eklemek için kullanılan Post metodu gösterilmiştir. Kullanıcı tarafından yollanan Restaurant modeline uygun olan veri unitofwork aracılığı ile repositoryde bulunan add fonksiyonuna gönderilip veritabanına eklenmiştir.

12

Delete metodu, silinmek istenilen verinin id değerini parametre olarak alır. Yapılacak işlem için unit of work sınıfında örneklenmiş repository sınıfında olan metod çağrılmaktadır.

13

Put metodu parametre olarak Restaurant model sınıfı formatında veri alır. Güncelleme yapmak için gerekli metoda yollar.

14

Örnek olarak belirli bir id değerine göre değer çekmeye bakalım. 57601c6da9fba760e3aeed8a ObjectId değerine karşılık gelen restaurant değeri aşağıdaki gibidir. Yapılacak REST işlemlerine göre veriler kullanılmak üzere paylaşılmaktadır.

15

Projenin kaynak kodları

Adapter Design Pattern

Daha önce planladığım ancak yazmayı ertelediğim tasarım şablonlarına devam ediyorum. Yazmaya başladığım şablon structural(yapısal) tasarım desenlerinden olan adapter tasarım şablonudur. Kısaca tanımını yapalım.

Adapter design pattern ile genellikle sistemimize uymayan sınıfları veya nesneleri, sistemimize adapte etmek için kullanırız. Çevremizde bir çok sistem adaptör mantığını kullanılarak birbirleri ile etkileşir. Örneğin hafıza kart adaptörleri; hafıza kartını bilgisayarımıza direkt olarak takamazsak adaptör kullanarak takarız ve işlemimizi gerçekleştiririz. Şarj için kullanılan adaptörler de bu kapsama girer. Yazılım geliştirme süreçlerinde de aynı mantık geçerlidir. Sistemimize yeni eklemek istediğimiz özellikleri barındıran arayüzü uyumsuz sınıfları veya nesneleri bu şablonu kullanarak sistemimize uyumlu hale getirmekteyiz. 3.parti kütüphaneleri projemize uyumlu hale getirmek gibi.

Temel olarak 2 uyumsuz arayüz arasında köprü görevi görür. 2 çeşit adapter pattern uygulaması vardır. Birincisi ve aşağıdaki uml’de gözüken sistem sınıf adapter yapısıdır. Miras tabanlı adapter işlemi yapar. Diğeri ise object tabanlı adapter yapısıdır. Bu yapı delegate yolu ile işlem yapar.

  • ITarget : ITarget arayüzü client tarafında kullanılan işlemleri gerçekleştirir. Kullanılan ana arayüz sınıfıdır.
  • Client : ITarget arayüzü ile etkileşime girmektedir. Adaptee edilmek istenen sınıf ile uyumsuzdur.
  • Adaptee : Sisteme eklemek istenilen özelliklerin bulunduğu arayüz sınıfıdır. ITarget arayüz sınıfı ile uyumlu değildir.
  • Adapter : Adaptee arayüzünü ITarget arayüzü ile bağlamaktadır. İçerisinde adaptee nesnesini barındırır. Adaptee yapısında olan özellikleri ve metodları adaptee üzerinden sağlamaya yaramaktadır.

Adapter tasarım şablonunu kullanarak basit bir örnek sistemi inceleyelim.

1- IEmployee sınıfı sistemde kullanılan ana arayüzdür. Void tipli salary metodu tanımlanmıştır.

1

2- Employee sınıfı bu arayüzü uygulamaktadır. Salary metodu içerisinde her çalışanın maaş değeri, constructordan dönen isim değeri eklenerek ekrana yazılır.

2

3- Manager sınıfı (adaptee) sisteme eklenmek istenmektedir. Bu sınıfta SalaryBonus metodu bulunmaktadır. Bu metod kullandığımız arayüze uymamaktadır.

3

4- EmployeeAdapter bizim adapter sınıfımızdır. Ana arayüzü ve eklenecek olan(adaptee) sınıfını uygulamaktadır.

4

5 – Çalışan Listesi oluşturuluyor. İki elemean normal employee sınıfından oluşturulmaktadır. Diğer eleman ise adapter sınıfından oluşturuluyor. Show metodu ile tüm çalışanlar listelenmektedir.

5

6 – Ekran görüntüsü aşağıdaki gibidir. John ve Jane adlı çalışanların maaş bilgisi gösterilmektedir. Mark adlı managerin maaş bonusu gösterilmektedir.

6

Adapter design pattern kullanarak yapılmış basit bir örneği inceledik. Daha kapsamlı örnekler internette mevcuttur.

 Kaynakça