<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Caner Patır</title>
    <description>The latest articles on DEV Community by Caner Patır (@canerpatir).</description>
    <link>https://dev.to/canerpatir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F231160%2F4412532b-4d91-48e1-8d4a-12c7fa708463.jpeg</url>
      <title>DEV Community: Caner Patır</title>
      <link>https://dev.to/canerpatir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/canerpatir"/>
    <language>en</language>
    <item>
      <title>DDD ve Mikroservis Kavramları Üzerine— Bounded Context  Mikroservis İlişkisi ve Tutarlılık</title>
      <dc:creator>Caner Patır</dc:creator>
      <pubDate>Sun, 15 Mar 2020 09:56:26 +0000</pubDate>
      <link>https://dev.to/canerpatir/ddd-ve-mikroservis-kavramlari-uzerine-bounded-context-mikroservis-i-liskisi-ve-tutarlilik-3i4l</link>
      <guid>https://dev.to/canerpatir/ddd-ve-mikroservis-kavramlari-uzerine-bounded-context-mikroservis-i-liskisi-ve-tutarlilik-3i4l</guid>
      <description>&lt;h3&gt;
  
  
  DDD ve Mikroservis Kavramları Üzerine— Bounded Context Mikroservis İlişkisi ve Tutarlılık
&lt;/h3&gt;

&lt;p&gt;Bir önceki yazıda bounded contextlerin domaine ait iş kurallarının mantıksal sınırları olduğundan bahsetmiştik (bkz: &lt;a href="https://dev.to/canerpatir/ddd-ve-mikroservis-kavramlari-uzerine-bounded-context-11ld-temp-slug-2236276"&gt;DDD ve Mikroservis Kavramları üzerine — Bounded Context&lt;/a&gt;). Yani bounded contextleri modellerken business kuralları üzerinden konuşuruz. Mikroservis için ise altyapısal gereksinimler gözetilerek oluşturulmuş teknik sınırlardır diyebiliriz. Yani, ölçeklenebilirlik, erişilebilir, yönetilebilirlik gibi mimari konular önemlidir. Buradan yola çıkarak bounded contextler ve mikroservisler arasında bire bir ilişki kurmanın anlamlı olduğunu söyleyemeyiz. Yani bir bounded context bir servistir gibi bir kural yoktur. Bir servis bir bounded context olabileceği gibi bir bounded context birden fazla servisi kapsayabilir ya da bir servis birden fazla bounded contexti kapsayabilir.&lt;/p&gt;

&lt;p&gt;Bounded contextin ürettiği asıl değer domain in farklı mantıksal alt birimleri içerisinde ortak bir dil oluşturmak ve bu sınırlar arasındaki ilişkiyi tanımlamaktır. Teknik ihtiyaçların öncelenmesi şartı ile servis sınırlarının belirlenmesi konusunda da etkili rol oynayabilir.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ubiquitous Language
&lt;/h4&gt;

&lt;p&gt;Bir kavramın farklı bounded contextler için sağladığı anlam farklı olabilir. E-ticaret domaininden örnek verecek olursak. Ürün kavramı, katalog bilgisi yöneten ekip için müşterinin satın alma deneyimini etkileyen, renk, beden, görsel gibi temel niteliklerin yönetimine dayalı iş kurallarını barındırır. Teslimat ekibi için ise sadece teslimatı sağlanacak bir paket içeriğidir ve renk, beden gibi özellik değerleri bu ekip için bir anlam ifade etmeyebilir. Burada, paketin en hızlı ve az maliyetli şekilde müşteriye ulaştırılması için gerekli iş kuralları önceliklidir.&lt;/p&gt;

&lt;p&gt;Peki bu farklılık teknik anlamda geleneksel bir uygulamada ne ifade eder ?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TBFZYo-L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHk84MlrGT01e8_6IfK6spg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TBFZYo-L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHk84MlrGT01e8_6IfK6spg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yukarıdaki görselden de faydalanarak, ilişkisel bir veri modeli üzerinde, product ve delivery nesnelerinin birbiri ile ilişkisel cebir (relational algebra) normalizasyon kuralları ile bağıntılı olduğunu gözlemlemekteyiz. DeliveryProduct tablosunda Product ve Delivery nesneleri arasındaki many-to-many ilişki olduğunu anlayabiliriz. Peki ya Product ve Delivery biribirinden bağımsız datastorelara sahip ayrı bounded context’ler içerisinde yer alsaydı modelleri nasıl ilişkilendirecektik?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Normalizasyon, ilişkisel veri modelinde bir düzenleme tekniğidir. Tablolardaki veri tekrarlarından ve insert, update, delete işlemleri esnasındaki tutarsızlıklardan kaçınabilmek için tabloları belli sistematiklerle ayrıştıran bir yaklaşımdır.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Madem product iki farklı bounded context için farklı anlam ifade ediyor öyleyse product nesnesini iki farklı context için tekrarlamakta bir kusur yok diyebilir miyiz?&lt;/p&gt;

&lt;p&gt;Aşağıdaki görsele göre; P_roduct_ nesnesi iki contextte de yer almaktadır. Ancak içerisinde bulundukları context için farklı iş mantığı kurallarını barındırıyor olabilirler. Örneğin; delivery context için product, &lt;em&gt;kilo&lt;/em&gt;, &lt;em&gt;adet&lt;/em&gt; gibi sadece teslimat kurallarına hizmet eden nitelikleri bünyesinde barındıran bir &lt;em&gt;değer tipi(value object)&lt;/em&gt; iken, product context için kategori bazlı özellikler barındıran, göresel içerik gibi konularda kendine has iş kuralları olan, katalog içeriğini oluşturan bir bileşen olabilir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7VtdReNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/571/1%2Am0wtHpE9v_cnffSh1xYbQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7VtdReNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/571/1%2Am0wtHpE9v_cnffSh1xYbQw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veri tekrarından kaçınmak için karmaşık normalizasyon kurallarına ihtiyaç duyuyorken, neden iki farklı databasede aynı veriyi tutuyoruz? Veri tekrarı tutarlılıkla ilgili problemlerle başımızı ağrıtmaz mı? Herhangi bir product nesnesinin “name’’i değiştiğinde delivery servisindeki product bu durumdan nasıl etkilenir? Örneğin sitemizin ürün detay sayfasında gördüğümüz ürün başlığı ile sipariş detay sayfasında gördüğümüz başlık arasında farklılık oluşmayacak mı? gibi bir sürü soruya gelin birlikte cevap bulmaya çalışalım.&lt;/p&gt;

&lt;p&gt;Product ve delivery farklı servisler olarak tasarladığımızı düşünelim. Bu servisler birbirinden bağımsız databaselere sahip olabilirler. Bu durumda, iki farklı servis içerisinde yer alan product nesnelerinde yapılacak değişiklikler bir &lt;strong&gt;transaction&lt;/strong&gt; olmaksızın gerçekleşecek ve veri tutarlılığı ile ilgili çözülmesi gereken yeni problemleri beraberinde gelecektir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tutarlılık (Consistency):&lt;/strong&gt; Tutarlılık, sistemi bir durumdan başka bir duruma geçirirken farklı sistem birleşenlerinin o durumla ilgili referans bütünlüğü sağlamasıdır. Örneğin, bir e-ticaret sisteminde kullanıcı bir ürün için başarılı bir sipariş kaydı oluşturdu ise aynı stoğu başka bir kullanıcıya da satmamak adına, ilgili ürüne ait stok bilgisinin sipariş miktarı kadar azaltılması beklenir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ancak, bu iki contextin business gereksinimleri açısından birbirinden ayrı olduğuna kanaat getirdiysek, product ve delivery birbirinden servis seviyesinde ayrılmalı mıdır? Doğru cevap yine yok :) Bu durum mikroservis dünyasının getirdiği problemlerden birisidir. Ancak şunu bilmeliyiz ki bu iki contexti business ihtiyaçları doğrultusunda ayırmamız, servis seviyesinde ayırmamız zorunluluğunu doğurmaz. Eğer servis seviyesinde bir ayrıştırma düşünüyorsak önceliklendirmemiz gereken konu ölçekleme gibi teknik ihtiyaçlardır. Örneğin; müşterilerin satın almadan çok kataloğunuzu gezme eğilimi gösterdiği zamanlarda product servisinizin daha fazla trafik aldığını gözlemleriz. Bu durumda product servisini ölçekleme zorunluluğu doğar. Kampanya gibi siparişin çok daha yoğun olduğu dönemlerde teslimat servislerinin ölçeklenmesi gerekir. Bu tarzda daha esnek bir ölçeklendirilebilirlik altyapısı istersek bu iki bileşeni servis olarak ayırabiliriz. Bu durum, ACID transactionlardan vazgeçmek zorunluluğu doğurabilir. Dolayısı ile tutarlılıkla ilgili yeni yaklaşımlara açık olmak gerekir. Önce tutarlılık neydi bir hatırlayalım.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strong Consistency?
&lt;/h4&gt;

&lt;p&gt;Geleneksel yaklaşımlarda tutarlılığı (consistency) sağlamak için atomic transactionlardan bolca faydalanırız. Transaction kapsamı içerisinde yapacağımız operasyonlar farklı nesneler üzerinde olsa bile atomik bir bütünlük içerisinde ele alınır. Böylelikle, sipariş kaydı oluşturuldu -&amp;gt; stock bilgisi güncellendi gibi bir operasyonda, “sipariş kaydı oluşturulamazsa stock bilgisi güncellenemez, stock bilgisi güncellenemezse sipariş kaydı oluşturulamaz” önermesini sağlamış oluruz. Operasyonlar topyekün olarak gerçekleşmiş olur (commit) ya da iptal edilir (rollback). Atomic transactionlar genelde database engine içerisinde ele alındığından, transaction kapsamı doğru tanımlandığı sürece bize bütünlük garantisi verir ve developerdan soyuttur. Veri bütünlüğünü düşünmek zorunda kalmayız. Database storage engine bunu bizim yerimize halleder.&lt;/p&gt;

&lt;p&gt;Peki ama modelimizde stock ve siparişler ayrı bounded contextlerse ve bunları ayrı servisler olarak dizayn edersek, tutarlılık konusunu nasıl ele alırdık? Aslında dağıtık sistemlerin uzun yıllardır baş etmeye çalıştığı problemlerin, mikroservislerle birlikte uygulama seviyesine kadar çıktığını görmüş olduk. Ancak, yeni olmayan bu problemlerin -bütün düşünce tarzımızı değiştirmemiz gerekse de- çözümlerinin de var olduğunu biliyoruz. Burada &lt;strong&gt;eventual consistency&lt;/strong&gt; kavramı hayatımıza giriyor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Eventual Consistency?
&lt;/h4&gt;

&lt;p&gt;Yukarıdaki sipariş adımlarını sepet durumunu da işin içerisine katarak genişletecek olursak. Örneğin: Sipariş kaydı oluşturuldu -&amp;gt; stock bilgisi güncellendi -&amp;gt; kullanıcı sepet içeriği güncellendi. Bunu daha fazla detaylandırıp sürecimize daha fazla adım ekleyebiliriz hatta ödeme sürecini de buna dahil edebiliriz. Ancak transaction sınırı (transaction boundry) genişledikçe, özünde birbirinden bağımsız hareket edebilecek contextlerin bir arada yaşama zorunluluğu ortaya çıkmış olur. Bu durumun, db lock’larından kaynaklı getirmiş olduğu performans problemlerini de beraberinde getirecektir. Üstelik, ödeme gibi harici bir sistemi (banka servisleri) dahil etmemizi gerektirecek bir süreç, aynı transaction kapsamı içerisinde ele almamız mümkün olmayan adımları da işlememizi gerektirebilir. O halde, sipariş, stok, sepet ve ödeme içerisindeki iş mantıklarını birbirinden ayırma yaklaşımına gidebiliriz. Ancak, artık db level transactionları bıraktığımıza göre tutarlılığı bir şekilde sağlamamız gerekecektir. Bu durumda eventual consistent yani nihai anlamda tutarlı bir sistem dizayn etmemiz gerekir.&lt;/p&gt;

&lt;p&gt;Nihai tutarlılık, değişen bir veri öğesinin değerinin, yeterli süre verildiğinde, tüm birimlerde aynı olacak şekilde dağıtılmasına dayalı bir tutarlılık yaklaşımıdır. Buna göre, tüm birimlerdeki değer, en son yapılan güncellemeyle tutarlı olacaktır. Öte yandan, yeterli zaman geçmeden, verinin birden fazla noktada tutarsız olacağını göz önünde bulundurmak gerekir. Bu duruma gecikme (latency) denir ve sistemin diğer aktörlerinin de (örneğin diğer mikroservislerin) bu gecikmeyi gözetecek şekilde davranmasını sağlamak gerekir. Şunu unutmamalıyız ki nihai tutarlılık nokta atış bir çözüm değildir ve uygun durumlarda tercih edilmelidir. Yani nihai tutarlılığın tercih edildiği sistemin &lt;strong&gt;gecikmeleri tolere edilebilecek karakteristiğe sahip olması&lt;/strong&gt;  gerekir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mikroservisler gibi dağıtık bilgi işlem ortamlarında, CAP teoremi tutarlılık(consistency), erişilebilirlik(availability) ve bölünebilme toleransını(partition tolerance) aynı anda garanti etmenin imkansız olduğunu ve geliştiricinin kendisi için en önemli üç taneden ikisini seçmek zorunda olduğunu varsayar. Buna göre, nihai tutarlılıkla birlikte A ve P yi tercih etmiş oluruz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency(Tutarlılık):&lt;/strong&gt; Dağıtık bir sistemde bir bileşene bir veri yazıldıktan sonra diğer bir bileşene bu verinin değeri sorulduğunda, bu bileşenin aynı değeri sağlayabilmesidir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Availability(Erişebilirlik):&lt;/strong&gt; Dağıtık bir sistemde, herhangi bir istemci bir değer sorduğunda o değerin herhangi bir versiyonuna mutlaka erişebilmelidir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Partition Tolerance (Bölünebilme Toleransı):&lt;/strong&gt; Sistem birbirinden bağımsız çalışabilen birimlere bölünebilmeli ve bu birimlerden birine herhangi bir sebepten erişilemese bile istemci gecikmeyle de olsa cevap alabilmelidir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Sonuç
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Servislerin sadece teknik ihtiyaçlar gözetilerek oluşturulması da yanlıştır. Bu tutum business açısından zayıf servisler ortaya çıkmasına neden olabilir. Business açısından hiçbir sorunu çözmeyen ama DevOps maliyeti oluşturan servisler istemeyiz.&lt;/li&gt;
&lt;li&gt;Consistency ve partition tolerence mikroservis gibi dağıtık mimarilerde bir ödünleşmedir (trade-off). Consistency problemleri bazen çok pahalı olabilir dolayısı ile mimari bunu tolere edebilecek bütünlükte tasarlanmalıdır.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>consistency</category>
      <category>captheorem</category>
      <category>mikroservis</category>
      <category>ubiquitouslanguage</category>
    </item>
    <item>
      <title>DDD ve Mikroservis Kavramları Üzerine — Bounded Context</title>
      <dc:creator>Caner Patır</dc:creator>
      <pubDate>Sun, 15 Mar 2020 09:53:43 +0000</pubDate>
      <link>https://dev.to/canerpatir/ddd-ve-mikroservis-kavramlari-uzerine-bounded-context-1fil</link>
      <guid>https://dev.to/canerpatir/ddd-ve-mikroservis-kavramlari-uzerine-bounded-context-1fil</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LCLTc-Ty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1011/1%2A6dMmiugD_jrCblA8PuBD6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LCLTc-Ty--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1011/1%2A6dMmiugD_jrCblA8PuBD6g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DDD ve Mikroservis Kavramları Üzerine — Bounded Context
&lt;/h3&gt;

&lt;p&gt;Geleneksel iş yapma biçimlerinin yerini, rekabetçi ve yenilikçi teknolojik çözümlere bırakması ile birlikte şirketlerin iş süreçlerinin dijitalleşmesi gerekliliği ortaya çıktı. Bununla beraber şirketlerin teknoloji departmanlarına yatırım yapması kaçınılmazdı ancak hızlı büyüyen teknoloji ekiplerinin tek merkezli ( &lt;strong&gt;monolith&lt;/strong&gt; ) uygulamalar üzerindeki hakimiyeti günden güne zorlaşıyor, code-base’ler kontrolden çıkacak şekilde büyüyordu. Bu da şirketleri &lt;strong&gt;ölçeklenebilirlikten&lt;/strong&gt; , &lt;strong&gt;test&lt;/strong&gt; ve &lt;strong&gt;refactor&lt;/strong&gt; edilebilirlikten uzaklaşmış yazılım sistemleri ile baş başa bırakmıştı. Bu durum firmaların değişen iş ihtiyaçlarına hızlı adapte olmama problemi ile yüzleşmesine neden oldu. &lt;strong&gt;Gelişime dirençli&lt;/strong&gt; ve &lt;strong&gt;yüksek maliyetli&lt;/strong&gt; yazılım sistemleri, firmaları rekabette epeyce geriye düşürüyordu. Bazı büyük teknoloji firmalarının önderliğinde, büyük uygulamaları farklı küçük servislere ayrıştıran service oriented architecture (SOA) yaklaşımı ortaya atıldı. Bu, büyük bir yazılım projesini daha iyi yönetilebilir küçük parçalara bölmeye dayalı mimarisel bir çözümdü. Ancak SOA, takip eden yıllarda yerini, kendi başına deploy edilebilen ( &lt;strong&gt;fine grained&lt;/strong&gt; ), birbirine zayıf bağımlılıklara bağlı ( &lt;strong&gt;loosly coupled&lt;/strong&gt; ) servislerden oluşan mikroservis yaklaşımına evrildi.&lt;/p&gt;

&lt;p&gt;Bu yaklaşımla hedeflenen;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kolay yönetilebilir (light weight) code-base’e sahip olmak&lt;/li&gt;
&lt;li&gt;Test edilebilirliği (testibility) arttırmak,&lt;/li&gt;
&lt;li&gt;Ölçeklenebilirliği (scalability) arttırmak,&lt;/li&gt;
&lt;li&gt;Esnekliği (felxibility) arttırmak,&lt;/li&gt;
&lt;li&gt;Yüksek erişilebilirliği (highly availability) sağlamak,&lt;/li&gt;
&lt;li&gt;Yeni özellikleri hızlıca release edebilmek (time to market),&lt;/li&gt;
&lt;li&gt;Organizasyonel yapı ile yazılım sistemi arasındaki uyumu sağlamaktı.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mikroservis yaklaşımı ile birlikte “teoride” yüzlerce yazılım mühendisi aynı projenin farklı modüllerinde paralel olarak çalışabilir, servisler birbirinden bağımsız olarak deploy edebilebiir, uygulamaların farklı modülleri farklı stratejiler ile ölçeklendirilebilir ve yeni bir gereksinim oluştuğunda sistemin küçük bir parçasında yapılan değişiklik ile iş gereksinimleri pazara çok hızlı bir şekilde çıkabilir. Ancak, kulağa hoş gelen bu değerleri üretebilmek için büyük ekiplerin, iş kuralları ve teknolojik gereksinimleri konusunda, nasıl organize olacağına dair bir sistematiğe, fikir birliğine ve ortak bir iletişim diline sahip olması gerekir. İşte tam burada &lt;strong&gt;domain driven design (DDD)&lt;/strong&gt; disiplini yazılım mühendislerine yeni yöntemler sunuyor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Domain Driven Design (DDD)?
&lt;/h4&gt;

&lt;p&gt;Bu kavramı anlamak için öncelikle “domain nedir” sorusuna güvenilebilir bir cevap vermek gerekir. Yazılımları gerçek dünya problemlerine çözüm üreten ve tekrar tekrar kullanılabilen makina prosedürleri olarak tanımlayabiliriz. Bahsettiğimiz bu “&lt;em&gt;gerçek dünya problemi&lt;/em&gt;”’nin çözümüne dair bilgi birikimine domain yani etki alanı denir. Örneğin bir ürünün, internet üzerinden en hızlı şekilde ve en uygun fiyat ile tüketiciye ulaştırılabilmesi problemi e-ticaret domainine ait bir problemdir. DDD ise bu bilgi birikimini daha çok açığa çıkararak, karmaşık domain probleminin çözümünü belli bir sistematiğe göre yazılımsal olarak modellemeyi sağlayan bir disiplindir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yüksek işbirliğine ihtiyaç duyulan ve doğası gereği belli bir karmaşıklık barındıran etki alanlarına &lt;strong&gt;collaborative domain&lt;/strong&gt; denmektedir. Genel olarak, DDD’nin bu karakteristiğe ait domain’ler için daha uygun bir çözüm olduğu kanısı hakimdir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DDD’nin stratejik ve taktiksel olmak üzere iki ayrı aşaması vardır. Stratejik DDD’de, iş kurallarına bağlı kalarak sistemin büyük ölçekli modelini tanımlarız. Stratejik DDD, birbirine gevşek bağlı birimleri ( &lt;strong&gt;bounded context&lt;/strong&gt; ) ve bunlar arasındaki ilişkiyi ( &lt;strong&gt;context map&lt;/strong&gt; ) tasarlamayı sağlayan disiplinleri belirler. Taktik DDD, implementasyona odaklanır ve yazılımsal implementasyonu oluşturmak için kullanabileceğimiz tasarım desenlerini sağlar. Bu tasarım desenleri entity, aggregate, value object, repository ve domain service gibi kavramları içerir (&lt;em&gt;ki bu yazıda taktik patternlerin detayına girmeyeceğiz — bunla ilgili başka bir post yayınlamayı düşünüyorum&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;DDD’nin üretttiği en önemli değer değişen iş kuralları üzerinde ortak bir dil oluşturarak büyük teknoloji ekipleri arasındaki iş birliğini ( &lt;strong&gt;collobration&lt;/strong&gt; ) arttırmaktır. DDD domaini kendine ait ortak bir dil barındıran, sınırları belirli, bağımsız bileşenlere ayıran bir yaklaşımı belirler. Oluşan bu ortak dile &lt;strong&gt;ubiquitous language,&lt;/strong&gt; bağımsız birimlere ise &lt;strong&gt;bounded context&lt;/strong&gt; denir. Bounded context DDD için modelleme açısından en önemli kavramlardan biridir ve DDD ile ilgili kaynaklarda sıkça karşılaşacağımız bir kavramdır. Gelin bunu detaylandıralım.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Bounded Context?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Karmaşık bir problemin çözümünden uyguladığımız yöntem, genellikle problemi daha küçük parçalara bölmek ve nispeten daha kolay olan bu küçük problemlere odaklanmaktır. Bounded context için karmaşık domain’in -kendi içinde tutarlı ve mümkün olduğunca bağımsız- daha küçük problem parçacıklarını temsil eden mantıksal sınırlardır (logical boundry) diyebiliriz. DDD’nin stratejik design başlığı altında yer alır ve bu yönüyle modelleme evresinde ortaya çıkan bir kavramdır. Contextler belirlenirken birbirine daha az bağımlı, birbirinden izole ve herbirinin otonom olması gibi değerler önceliklidir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xNtK-WEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/821/1%2Asl5dKXoWONDmyqnAPXDYJg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xNtK-WEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/821/1%2Asl5dKXoWONDmyqnAPXDYJg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Bounded Context sınırlarını nasıl belirleriz?
&lt;/h4&gt;

&lt;p&gt;Bounded context’lerin belirlenmesi konusu DDD’nin stratejik tasarım ( &lt;strong&gt;strategic design&lt;/strong&gt; ) evresini ilgilendiren bir konudur. Stratejik tasarım evresi modelleme işnin yapıldığı süreçtir ve implementasyondan bağımsız bir konudur.&lt;/p&gt;

&lt;p&gt;Bu süreç çoğu kaynakta &lt;strong&gt;context discovery&lt;/strong&gt; olarak belirtilir. Dolayısı ile bir keşif serüvenidir diyebiliriz. Bu yönüyle baktığımızda, context boundary’lerin reçetesi veya nokta atışı bir yöntemi olduğundan bahsedemeyiz. Bu konuyla ilgili olarak çoğu DDD mecrasında &lt;strong&gt;heuristic&lt;/strong&gt; ifadesini görebilirsiniz. Bu, hissiyati ya da içgüdüsel anlamına gelir. Yani bu süreç, business ihtiyaçları, modellemeyi yapan insanlar, teknik kısıtlar, ekip içi iletişim gibi bir sürü parametreye bağlıdır. Ancak, modelleme sürecinin tamamı ile belirsiz bir hal almaması için DDD dünyası bazı önemli konulara işaret eder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain knowledge (Domain yetkinliği):&lt;/strong&gt; Doğru bir model için önce problemin doğru anlaşılması ve analiz edilmesi gerekir. Ayrıca, farklı domainler kendine has iş kuralları barındırır. Bu kuralları doğru anlamak, saklı olanları da açığa çıkarabilmek için işbirliği ve iterasyon büyük önem taşır.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collobration (İşbirliği):&lt;/strong&gt; Doğru modeli bize hazır halde sunan bir araç olmadığına göre, bu süreç insanlar tarafından yürütülecektir. Doğru model için daha fazla domain knowledege, bunun için de farklı bakış açısı ve vizyonlar gerekir. Ancak bu durum modelleme sürecine her önümüze geleni dahil edeceğimiz anlamına gelmez. Etkili bir model için sürecin domain uzmanları ( &lt;strong&gt;domain expert&lt;/strong&gt; ) tarafından yönlendirilmesi önemlidir. Domain expert kavramı bir rol ya da title değildir. Problemi çok iyi anlamış hatta o problemi yaşayan biri olabilir. Buradan yola çıkarak domain expert olarak en iyi örnek aslında müşterinin ta kendisidir diyebiliriz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iteration (Tekerrür):&lt;/strong&gt; Modellemenin bir keşif serüveni olduğundan bahsettik. Ancak bu keşif mükemmeli aramak değildir. Mükemmel modeli aramaktansa, modelimizdeki eksikleri zaman içerisinde iyileştirmek, ürünün pazara daha hızlı çıkması açısından ( &lt;strong&gt;time to market&lt;/strong&gt; ) akılcı bir yaklaşımdır. Gelişen pazar koşullarına bağlı iş kurallarının da sürekli değiştiğini hesaba katarsak, modelin bir kere belirlendikten sonra, bir daha asla değişmeyeceğinden bahsedemeyiz. Domain uzmanları ile iletişim içerisinde modelimizi sürekli geliştirmeliyiz. Teknik bakış açısıyla DDD’nin continuous refactoring ve continuous delivery konularına da dokunduğundan bahsedebiliriz.&lt;/p&gt;

&lt;p&gt;Diğer bir önemli etken de organizasyondur. Sistemleri yapanlar organizasyonlardır ve iletişim alışkanlıkları yaptıkları çözüme yansır (bkz. &lt;a href="https://en.wikipedia.org/wiki/Conway%27s_law"&gt;Conway’s law&lt;/a&gt;). Bu duruma kanıt olarak, benzer işi yapan iki farklı şirkete baktığımızda, aynı problemi çözüyor olsalar bile yazılımsal modelin farklılıklar gösterdiğini görebiliriz.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sonuç
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;DDD, kompleks domainlerde uygulandığında fayda üreten bir pratiktir.&lt;/li&gt;
&lt;li&gt;DDD’nin strategic design evresinde domain knowledge, doğru modelleme için büyük önem taşır.&lt;/li&gt;
&lt;li&gt;Domain knowledge açığa çıkarmak için domain expertler ile birlikte çalışmak gerekir.&lt;/li&gt;
&lt;li&gt;DDD, collobrative bir yöntemdir domain expertler ve teknik ekipler arasında güçlü bir iletişim sağlanmalıdır.&lt;/li&gt;
&lt;li&gt;DDD, mikroservis gibi mimarisel yaklaşımlarda yönlendirici olabilir ancak belirleyici unsur değildir. Servis sınırları teknik concernler öncelenerek oluşturulur.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yazının devamı — &lt;a href="https://medium.com/@canerpatir/ddd-ve-mikroservis-kavramlar%C4%B1-%C3%BCzerine-bounded-context-mikroservis-i%CC%87li%C5%9Fkisi-ve-tutarl%C4%B1l%C4%B1k-9e7ac4a3532f"&gt;DDD ve Mikroservis Kavramları Üzerine — Bounded Context Mikroservis İlişkisi ve Tutarlılık&lt;/a&gt;&lt;/p&gt;

</description>
      <category>boundedcontext</category>
      <category>domaindrivendesign</category>
      <category>ddd</category>
      <category>mikroservis</category>
    </item>
    <item>
      <title>Kotlin Coroutine — Asenkron ve Paralel Programlama</title>
      <dc:creator>Caner Patır</dc:creator>
      <pubDate>Wed, 18 Sep 2019 13:42:18 +0000</pubDate>
      <link>https://dev.to/canerpatir/kotlin-coroutine-asenkron-ve-paralel-programlama-37l</link>
      <guid>https://dev.to/canerpatir/kotlin-coroutine-asenkron-ve-paralel-programlama-37l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fn8xcfRj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/997/1%2AMeAzvIUCrkcBgGkd2TRBTw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fn8xcfRj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/997/1%2AMeAzvIUCrkcBgGkd2TRBTw.gif" alt="kotlin coroutine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Kotlin Coroutine — Asenkron ve Paralel Programlama
&lt;/h3&gt;

&lt;p&gt;Asenkron ve paralel programlama farklı teknoloji ekosistemlerinde farklı anlamlar ifade ettiği için yazıya başlamadan önce bu kavramlara açıklık getirmek istiyorum.&lt;/p&gt;

&lt;h4&gt;
  
  
  Paralel programlama (Parallelism)
&lt;/h4&gt;

&lt;p&gt;Bir görevin paralel olarak işlenebilecek daha küçük alt görevlere ayrılarak birden fazla CPU’da, &lt;strong&gt;threadler&lt;/strong&gt; vasıtası ile, paralel olarak yürütülmesi anlamına gelir. Paralel işlemler gereken veri ve kaynak bakımından biribirinden bağımsızdır ve çoğunlukla &lt;strong&gt;senkronizasyona&lt;/strong&gt; ihtiyaç duymazlar. Örnek verecek olursak… bir veri kaynağından (DB, filesystem vs.) idendifier’larını bildiğimiz bir veri seti okuyacaksak, bunları belli parçalara bölüp parallel bir şekilde toplayabiliriz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PtOJdY1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/286/1%2AvIjs55BVSRjqvUcgBKVakA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PtOJdY1X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/286/1%2AvIjs55BVSRjqvUcgBKVakA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Asenkron programlama (Concurrency)
&lt;/h4&gt;

&lt;p&gt;Bir uygulamanın aynı anda (concurrency) birden fazla görevde ilerleme kaydettiği anlamına gelir. Ancak bu işler paralel olarak farklı &lt;strong&gt;thread&lt;/strong&gt; lerde &lt;strong&gt;işlenmeyebilir&lt;/strong&gt;. Uzun süren IO görevlerinin CPU’yu bloklamamsı amacıyla kullanılır (non-blocking IO). Bir threadde IO işlemi sürerken o threadin bloklanmayarak, başka görevlere tahsis edilmesi ve CPU’nun yüksek utilizasyon ile kullanılması esasına dayalı bir görevdir. Bunu context switch teknikleri kullanarak sağlar. Bu yöntemin uygulanmasındaki zorluk alt görevler arasındaki senkronizasyonu sağlamaktır. Modern programlama dilleri senkronizasyon problemine derleyici seviyesinde çözümler üretmiştir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kotlin&lt;/strong&gt; programlama dili bu yöntemi sağlayabilmek için &lt;strong&gt;coroutine&lt;/strong&gt; denen bir yapı sunar. Coroutine’ler alt görevleri temsil eder ve &lt;strong&gt;dispatcher&lt;/strong&gt; denen bir yapı vasıtası ile görevler arasındaki senkronizasyon sağlanır. . Özetle, dispatcher threadlerin görevler arasında paylaşımı yani context switch işinden sorumludur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8K7enRK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/276/1%2AuRQkPy0VV4MqX2QfjY_OYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8K7enRK5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/276/1%2AuRQkPy0VV4MqX2QfjY_OYw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yazımın devam eden kısmında &lt;strong&gt;Kotlin&lt;/strong&gt; coroutine ile nasıl asenkron programlama yapabileceğimizden bahsedeceğim.&lt;/p&gt;

&lt;h4&gt;
  
  
  Coroutine nedir ?
&lt;/h4&gt;

&lt;p&gt;Öncelikle belirtmem gereken konu, coroutine’lerin &lt;strong&gt;thread olmadığıdır&lt;/strong&gt;. Kotlin ekibi coroutine’leri “ &lt;strong&gt;lightweight thread&lt;/strong&gt; ” olarak tanımlasa da bu tanım communitynin algısına girebilmek için kullanılan bir benzetmedir. Coroutinei tanımlamak istersek thread tarafından yürütülen görev parçalarıdır diyebiliriz. Başlıktaki gif’den de anlaşılabileceği gibi herhangi bir thread x anında bir coroutine’i alıp işletebilir. Ancak bu threadin ilgili coroutine’i bitene kadar bekleyeceği anlamına gelmez. Bloklayıcı bir bölüme gelindiğinde (suspension point) thread coroutine’i bırakır ve başka bir coroutine’i işletmeye başlayabilir (context switch). Suspend olan görev, işini bitirdiğinde tekrar başka bir thread tarafından işletimine devam edilebilir. Böylelikle thread’ler bloklanmadan verimli bir şekilde kullanılmış olur. Bunu &lt;strong&gt;CoroutineDispatcher&lt;/strong&gt; organize eder. CoroutineDispatcher context switching için &lt;strong&gt;suspend&lt;/strong&gt; keyword’ü ile etiketlenmiş &lt;strong&gt;özel function’&lt;/strong&gt; ları kullanır. Coroutine ile kod örneklerine geçmeden önce suspend functionların iyi anlaşılması gerekmektedir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CXjTU7fZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/720/1%2A_YqtHUC9Y84I46ygsFHfnw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CXjTU7fZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/720/1%2A_YqtHUC9Y84I46ygsFHfnw.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Suspend function
&lt;/h4&gt;

&lt;p&gt;Coroutine’lerin belli suspension pointlerde context switche girdiğinden bahsetmiştim. Bu noktaları derleyiciye geliştirici kendi deklare etmek durumundadır. Bu deklarasyonlar ilgili methodu &lt;em&gt;suspend&lt;/em&gt; keywordü ile etiketleyerek sağlanır.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Özetle; suspend functionlar, mevcut threadi bloke etmeden coroutinin yürütülmesini askıya alır. Böylelikle thread başka bir corutinenin işletilmesine başlar ve cpu daha verimli bir şekilde kullanılmış olur.&lt;/p&gt;

&lt;p&gt;Suspend functionlarla ilgili bir başka bilinmesi gereken konu da sıralı işletildikleridir. Yani dönüş değeri almadan ya da kodun geri kalanını çalıştırmadan önce, çağrılan suspend functionın yürütülmesini beklememiz gerekir. Bu durum asenkron operasyonların Kotlin ile ne denli kolay olduğuna bir kanıt niteliğindedir. Özetle, asenkron kod yazımının, normal yazımdan hiçbir &lt;strong&gt;farkı yoktur&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation1 done after 1 second
operation2 done after 2 seconds and result: hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Suspend functionlar diğer dillerin asenkron yazımdan farklı olarak, geriye özel veri tipleri dönmek zorunda değillerdir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java — Future, Flux, Mono, Single, Observable ve binlercesi :)&lt;/li&gt;
&lt;li&gt;Javascrip t— Promise&lt;/li&gt;
&lt;li&gt;C# — Task&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Yeni bir coroutine başlatma
&lt;/h4&gt;

&lt;p&gt;Kotlin standart kütüphanesi, coroutine başlatmak için &lt;strong&gt;coroutine builder&lt;/strong&gt; denen yapıları barındırır. Coroutine builder, belirli bir suspend fonksiyonu sarmalayan ve işletilmesini sağlayan fonksiyonlardır. Yani, yeni bir coroutine başlatmak için kullanırız. Bunlardan başlıcalarına göz atacak olursak.&lt;/p&gt;
&lt;h4&gt;
  
  
  CoroutineScope.Async
&lt;/h4&gt;

&lt;p&gt;Geriye değer dönen asenkron operasyonların işletilmesi için kullanılır. Beklenen sonucu almak için &lt;strong&gt;Deffered&lt;/strong&gt; dönüş tipi kullanır. Deferred, Javadaki &lt;em&gt;Future&lt;/em&gt; veya Javascript dilindeki &lt;em&gt;Promise&lt;/em&gt; in karşılığıdır diyebiliriz_._ Sonucu beklemek için Deffered sonucun &lt;strong&gt;await&lt;/strong&gt; methodunu çağırmak gerkir. Await bir suspend functiondır.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h4&gt;
  
  
  CoroutineScope.Launch
&lt;/h4&gt;

&lt;p&gt;Geriye dönüş tipi gerektirmeyen, arka planda işletilecek operasyonlar için kullanılan builder tipidir. &lt;strong&gt;Fire and forget&lt;/strong&gt; mantığı ile çalışabilecek işler için uygundur.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Runblocking&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;İlgili coroutine tamamlanana kadar, mevcut threadin bloke edilmesini sağlar. Coroutine içerisinde kullanılmamalıdır. Genelde blocking tarzda yazılmış koda coroutine scope bağlamak için ya da test amaçlı kullanılır. Yani normal dünya ile suspending dünya arasında köprü görevi görür. Bütün kod bloğu uçtan uca non-blocking tarzda yazılmışsa kullanımına gerek yoktur.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kotlin ekibi coroutine scope içerisinde thread bloklayacak yaklaşımlardan kaçınılmasını önerir. Bu sebeple, runBlocking’in coroutine içerisinde kullanmaktan kaçınmalıyız. Eğer runBlocking kullanılacaksa, hiyerarşide daima en tepede yer almalıdır.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Eşzamanlı İşletim
&lt;/h4&gt;

&lt;p&gt;Coroutineler eş zamanlı işletime de olanak sağlar. Aşağıdaki kod örneğinde eş zamanlı ve sıralı işletimin karşılaştırmasını görebilirsiniz.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation1: 247 ms
operation2: 5112 ms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Dispatcher — I/O ve CPU bağımlı işler
&lt;/h4&gt;

&lt;p&gt;Kotlin coroutine altyapısında dispatcher denen nesneler vasıtasıyla senkronizasyon yaptığından bahsetmiştik. Dispatcherların reactive frameworklerdeki (örn: rxJava) &lt;strong&gt;scheduler&lt;/strong&gt; nesnesine karşılık geldiğini düşünebiliriz. Corotuineler CPU açısından hiçbir anlam ifade etmeyen basit görev abstractionlarıdır. Dispatcher, coroutin yürütmesinden sorumludur t anında bir coroutine’i alıp threadpoolda bir threade atayarak işletilmesini sağlar ve gerektiğinde coroutine’i suspend ederek threadin başka bir coroutine yürütmesini sağlayabilir. Bu bağlamda, dispatcherlar coroutine’leri CPU için anlamlı hale getirmiş olur diyebiliriz.&lt;/p&gt;

&lt;p&gt;Ancak burada dikkat edilmesi gereken nokta ilgili işin networkden ya da filesystemden okuma yazma yapan I/O ağarlıklı bir iş mi yoksa yüksek aritmetik ve mantıksal operasyon barındıran CPU intensive bir iş mi olduğudur. Kotlin coroutine bu tip operasyonları I/O ya da CPU yoğun işlere özelleşmiş thread poollarda ele alır. Kotlin’e ilgili coroutine’in hangi kapsamda ele alıncağının bildirilmesi &lt;strong&gt;yazılım geliştiricinin sorumluluğundadır&lt;/strong&gt;. Bunun için Kotlin, &lt;em&gt;kotlinx.coroutines&lt;/em&gt; paketi içerisinde aşağıdaki öntanımlı dispatcherları barındırır.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dispatchers.Default&lt;/strong&gt; : Herhangi bir dispatcher belirtilmemişse, tüm coroutine üreticileri tarafından kullanılan varsayılan dispatcherdır. CPU yoğun görevlerin yürütülmesi için uygun seçimdir. (RxJava’daki Schedulers.Computation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dispatchers.IO&lt;/strong&gt; : I/O yoğun işlemler için kullanılır. ( RxJava’daki Schedulers.IO)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;I/O yoğun işe örnek olarak databaseden yaptığımız okuma yazmaları veya http çağrılarını, CPU yoğun işe ise hash operasyonu ya da görsel işlemeyi örnek gösterebiliriz. Eğer kurumsal bir uygulama geliştiriyorsak ağırlıklı olarak databaseden okuma yazma yaparız bu da I/O yoğun bir uygulamamız olduğu anlamına gelir. Yazımın önceki bölümlerinde bir I/O işlemi sürerken, threadin bloke edilmeksizin başka kaynaklara tahsis edilebileceğinden bahsetmiştim. Coroutine ile hedeflenen tam da budur ve bu durum coroutine kullanımının kurumsal uygulamalar için oldukça mantıklı olduğu anlamına gelir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1R-slGyS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2AcxTEI5VMoxiIiyImKtWEsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1R-slGyS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2AcxTEI5VMoxiIiyImKtWEsQ.png" alt=""&gt;&lt;/a&gt;CPU bloklayan bir IO operasyonu&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VIADjXMs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/512/1%2ABYcFmqG4CaObLkqyrpXFBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VIADjXMs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/512/1%2ABYcFmqG4CaObLkqyrpXFBw.png" alt=""&gt;&lt;/a&gt;Non-Blocking IO operasyonu&lt;/p&gt;

&lt;h4&gt;
  
  
  Özet
&lt;/h4&gt;

&lt;p&gt;Asenkron işlemler günümüzde çoğu yazılım geliştiricinin bir şekilde içerisinde yer aldığı ya da farkında olmadan yer almak zorunda olduğu bir durumdur. Örneğin, bir web uygulaması geliştiriyorsak concurrency bizim için kritiktir. İstemcilere sağlıklı bir hizmet verebilmek için, uygulamamızın birim zamanda karşılayabildiği istek sayısını ( &lt;strong&gt;throughput&lt;/strong&gt; ) en yüksekte tutmamız gerekir. Veya bir client uygulaması geliştiriyorsak, kullanıcı deneyimi açısından, arkaplanda yaptığımız işlemlerin kullanıcının UI üzerinde yaptığı işlemleri bloke etmemesini sağlamamız gerekir. Önceleri bu problemlerin çözümü için multi-threading tekniklerini kullansak da senkronizasyon problemi ve kullanımdaki zorluklar, yazılım endüstrisini bu konuda yeni çözümlerin arayışına itmiştir. Bu bağlamda, java ekosisteminde &lt;strong&gt;rxJava&lt;/strong&gt; , Spring’de &lt;strong&gt;Reactor&lt;/strong&gt; , c#’da &lt;strong&gt;async/awai&lt;/strong&gt; t, Golang’da &lt;strong&gt;goroutine&lt;/strong&gt; gibi daha yüksek seviye çözümler yazılım geliştiricilerin hizmetine sunuldu. Bütün bu çözümlerin ortak noktası yazılım geliştiriciyi karmaşık thread operasyonlarından soyutlayarak, önceden optimize edilmiş bir ortam sunmaktır. Kotlin ekibinin sunduğu çözüm ise coroutine olmuştur. Yazımda kotlin coroutine kullanımına ve kavramlara dair genel bilgiler vermek istedim. Kotlin coroutine’leri kullanarak, I/O ağırlıklı bir uygulamanın, aynı kaynak kullanılarak daha fazla istek karşılayabilmesini sağlayabiliriz. Bunu uygulamasını ve karşılaştırmalı yük testlerini, önümüzdeki haftalarda yeni bir medium postu ile paylaşacağım. Yeni yazımda görüşene dek şimdilik hoşçakalın :)&lt;/p&gt;




</description>
      <category>asyncawait</category>
      <category>kotlin</category>
      <category>coroutine</category>
      <category>asyncfunctions</category>
    </item>
  </channel>
</rss>
