﻿
{"id":22106,"date":"2021-07-11T22:21:14","date_gmt":"2021-07-11T22:21:14","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=22106"},"modified":"2021-07-11T22:21:14","modified_gmt":"2021-07-11T22:21:14","slug":"domain-driven-design-stratejik-ve-taktiksel-olarak-derinlemesine-inceleme","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/domain-driven-design-stratejik-ve-taktiksel-olarak-derinlemesine-inceleme\/","title":{"rendered":"Domain Driven Design &#8211; Stratejik ve Taktiksel Olarak Derinlemesine \u0130nceleme"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Yeni bir projeye ba\u015flanaca\u011f\u0131 vakit projenin toplam net s\u00fcresini \u00f6ng\u00f6rebilmek i\u00e7in k\u00e2h sezgisel k\u00e2h tahmine dayal\u0131 alt k\u0131r\u0131l\u0131mlar olu\u015fturmaya \u00e7al\u0131\u015f\u0131r\u0131z. Bu k\u0131r\u0131l\u0131mlar e\u015fli\u011finde projenin anatomisini periyodik olarak daha hesaplanabilir hale getirerek, izafi a\u00e7\u0131dan g\u00f6z \u00f6n\u00fcne sermi\u015f oluruz. Tabi genel anlamda bu u\u011fra\u015fta ne \u00f6l\u00e7\u00fcde ba\u015far\u0131l\u0131 oldu\u011fumuz ayr\u0131 bir konu olsa da burada niyetimiz stratejik a\u00e7\u0131dan projenin cephesel haritas\u0131n\u0131 tam olarak masaya yat\u0131rabilmektir. \u00d6zellikle b\u00fcy\u00fck projelerde, projenin kapsam\u0131ndan dolay\u0131<span style=\"font-size:11px;\">(ki bu kapsam\u0131 yaz\u0131m\u0131z\u0131n devam\u0131nda alan, etki alan\u0131 ya da domain \u015feklinde nitelendirece\u011fiz)<\/span> kaynaklanan bilgi eksikli\u011fi nedeniyle bazen zaman\u0131 tahmin etmek neredeyse imkans\u0131z hale gelebilmektedir. Bu durumda, ger\u00e7ekte ne yapmam\u0131z gerekti\u011fini ve nas\u0131l yapaca\u011f\u0131m\u0131z\u0131 tam olarak bilemeyece\u011fimizden dolay\u0131 izafi olarak tahmin edilen zaman ya haddinden fazla uzun ya da k\u0131sa olabilmektedir. \u0130\u015fte bu \u00f6ng\u00f6r\u00fclebilirli\u011fi kuvvetlendirmek ve ilgili projenin kapsam\u0131ndaki bilinmeyen terminolojik terimlerin ve bilgilerin t\u00fcm personeller taraf\u0131ndan anla\u015f\u0131labilir hale getirebilmek i\u00e7in bir standart geli\u015ftirilmesi gerekmektedir.<\/p>\n<p>Hadi diyelim ki, \u00fc\u00e7 a\u015fa\u011f\u0131 be\u015f yukar\u0131 \u00f6ng\u00f6r\u00fclerle temellendirilmi\u015f ve belirli bir noktaya kadar getirilmi\u015f bir projede bazen de hi\u00e7 \u00f6ng\u00f6r\u00fclemeyen ekstra i\u015flere ya da mod\u00fcllere sonradan ihtiya\u00e7 duyulabilmektedir. \u0130\u015fte b\u00f6yle bir durumda geli\u015ftiriciler a\u00e7\u0131s\u0131ndan \u00f6nceden yaz\u0131lm\u0131\u015f kodun ne yapt\u0131\u011f\u0131n\u0131 hat\u0131rlamak ve hatta tekrardan anlamak neredeyse imkans\u0131z hale gelebilmektedir. \u0130\u015fte bu durumda da yaz\u0131l\u0131mc\u0131lar a\u00e7\u0131s\u0131ndan kodu h\u0131zl\u0131 hat\u0131rlayabilmek ve bir standart haline getirebilmek i\u00e7in ba\u015flang\u0131\u00e7ta uygun kurallar\u0131n getirilmesi ve o kurallar \u00e7er\u00e7evesinde kodun geli\u015ftirilmesi gerekmektedir.<\/p>\n<p>Yukar\u0131da bahsedilen proje s\u00fcre\u00e7lerinde ya\u015fanan s\u0131k\u0131nt\u0131lar\u0131 \u00f6zetlersek e\u011fer; proje kapsam\u0131ndan kaynakl\u0131 olas\u0131 terminoloji ve bilgi eksikli\u011fi y\u00fcz\u00fcnden meydana gelen hesaplamadaki tutars\u0131zl\u0131klar yahut geli\u015ftiriciler a\u00e7\u0131s\u0131ndan ya\u015fanabilen olas\u0131 kod karma\u015fas\u0131 ve geriye d\u00f6n\u00fck mimarisel ya da tasar\u0131msal kopu\u015flar dikkat ederseniz hep projelerin etki alan\u0131yla ilgili \u00e7\u00f6z\u00fcm getirebilece\u011fimiz noktalara temas etmektedir. \u0130\u015fte t\u00fcm projelerde, i\u015fin kavramsal mant\u0131\u011f\u0131n\u0131 ve etki alan\u0131n\u0131 geli\u015ftirici olanlar i\u00e7in koda yans\u0131tan, geli\u015ftirici olmayanlar i\u00e7in ise daha anla\u015f\u0131l\u0131r ve s\u00fcrd\u00fcr\u00fclebilir k\u0131lan en az\u0131ndan olay\u0131 bu kuramsal a\u00e7\u0131dan de\u011ferlendirmemizi savunan <em><strong>Domain Driven Design<\/strong><\/em> yakla\u015f\u0131m\u0131n\u0131 baz alarak bu sorunlara kolayca \u00e7\u00f6z\u00fcm bulabilir ve ortadan kald\u0131rabiliriz, kald\u0131rmay\u0131 ama\u00e7layabiliriz \ud83d\ude42<\/p>\n<p>Bu i\u00e7eri\u011fimizde <em>Domain Driven Design<\/em>(DDD)&#8217;\u0131n stratejik a\u00e7\u0131dan ne oldu\u011funu, neleri savundu\u011funu detayl\u0131ca inceleyecek ve ard\u0131ndan taktiksel a\u00e7\u0131dan DDD&#8217;nin hangi terimleri g\u00fcnl\u00fck hayat\u0131m\u0131za kazand\u0131rd\u0131\u011f\u0131n\u0131 ve mimarilerimize ne gibi \u015fekiller verebildi\u011fini tart\u0131\u015f\u0131yor olaca\u011f\u0131z. Buyrun ba\u015flayal\u0131m&#8230;<\/p>\n<h3>Domain Driven Design Nedir?<\/h3>\n<blockquote><p><em style=\"color:purple;\">Domain Driven Design, ger\u00e7ek d\u00fcnyadaki i\u015f modellerini herkesin anlayabilece\u011fi ortak bir dil(Ubiquitous Language) ile olu\u015fturarak dijital d\u00fcnyaya uyarlamak i\u00e7in yaz\u0131l\u0131mlar\u0131n nas\u0131l modellenmesi gerekti\u011fi konusunda bir felsefeyi savunur.<\/em><\/p><\/blockquote>\n<p>Domain Driven Design&#8217;\u0131 anlayabilmek i\u00e7in \u00f6ncelikle &#8216;Domain&#8217; kelimesinin ne oldu\u011funu anlamam\u0131z gerekmektedir. Mevzu bahis konumuzun kitab\u0131n\u0131n yazar\u0131 olan Eric Evans&#8217;a g\u00f6re Domain;<\/p>\n<blockquote><p>Her yaz\u0131l\u0131m\u0131n kendine has olaylar\u0131 ve ilgi alanlar\u0131 vard\u0131r.<\/p><\/blockquote>\n<p>\u0130\u015fte buradaki ilgi alan\u0131 Domain&#8217;e kar\u015f\u0131l\u0131k gelmektedir. Bunu \u015f\u00f6yle \u00f6rneklendirebiliriz: Bir market y\u00f6netim sistemi in\u015fa edece\u011fimizi d\u00fc\u015f\u00fcnelim. Bu i\u015fi &#8220;Market Y\u00f6netimi&#8221; \u015feklinde nitelendirmek sizce do\u011fru mu? Baz\u0131lar\u0131n\u0131z evet diyebilir ama ger\u00e7ekten \u00f6yle mi? Misal, kurulacak sistem bir s\u00fcper market i\u00e7in ise bu marketten farkl\u0131 olacakt\u0131r. \u00d6yle de\u011fil mi? Bu y\u00fczden ilgi alan\u0131m\u0131z\u0131 isimlendirirken \u00f6ncelikle spesifik\/\u00f6zel olmaya dikkat etmeli ve yapaca\u011f\u0131m\u0131z i\u015fe uygun bir isimlendirmeyle ba\u015flamal\u0131y\u0131z. Evet, e\u011fer bu bir s\u00fcper market y\u00f6netim sistemiyse o halde &#8220;S\u00fcper Market Y\u00f6netimi&#8221; \u015feklinde isim vermemiz &#8220;Market Y\u00f6netimi&#8221; isminden daha mant\u0131kl\u0131, a\u00e7\u0131klay\u0131c\u0131 ve anlaml\u0131 olacakt\u0131r. B\u00f6ylece yaz\u0131l\u0131m\u0131m\u0131z\u0131n Domain&#8217;i(yani ilgi\/etki alan\u0131) isimsel olarak net belirlenmi\u015f olacakt\u0131r.<\/p>\n<p><em>Domain Driven Design<\/em>&#8216;\u0131n, &#8216;Domain&#8217; kelimesine a\u00e7\u0131kl\u0131k getirdikten sonra &#8216;Driven Design&#8217; k\u0131sm\u0131n\u0131 da a\u00e7arsak e\u011fer; proje yakla\u015f\u0131m\u0131m\u0131z\u0131n &#8220;<em>tasar\u0131m akl\u0131 kim<\/em>&#8221; sorusunu soran k\u0131sm\u0131d\u0131r. Bunu da \u00f6rneklendirmek i\u00e7in <em>Data Driven Design<\/em>&#8216;\u0131 ele alal\u0131m. Ad\u0131 ge\u00e7en yakla\u015f\u0131m, mevcut problemi data\/veri temelli bir \u015fekilde analiz etmeye ve \u00e7\u00f6zmeye \u00e7al\u0131\u015fan bir stratejiye sahiptir. Benzer \u015fekilde ilgili kal\u0131b\u0131 -Ahmet Driven Design- olarak kurgularsak var olan problemi Ahmet temelli bir \u015fekilde ele almay\u0131 \u00f6nermektedir. Haliyle <em>Domain Driven Design<\/em>&#8216;da var olan ve ya\u015fanan problemlerin Domain esas al\u0131narak analiz edilmesi ve \u00e7\u00f6z\u00fclmesi gerekti\u011fini savunan ve bunun i\u00e7in Domain&#8217;in net bir \u015fekilde anla\u015f\u0131lmas\u0131n\u0131n gerekli oldu\u011funu s\u00f6yleyen bir felsefedir.<\/p>\n<blockquote><p><em style=\"color:green;\">Domain Driven Design, var olan ve ya\u015fanan problemlerin Domain esas al\u0131narak analiz edilmesi ve \u00e7\u00f6z\u00fclmesi gerekti\u011fini savunan ve bunun i\u00e7in Domain&#8217;in net bir \u015fekilde anla\u015f\u0131lmas\u0131n\u0131n gerekli oldu\u011funu s\u00f6yleyen bir felsefedir.<\/em><\/p><\/blockquote>\n<p>DDD&#8217;yi \u00f6ncelikle stratejik a\u00e7\u0131dan ele alarak teorik yap\u0131lanmas\u0131n\u0131 incelemekte fayda olacak kanaatindeyim. O y\u00fczden hi\u00e7 vakit kaybetmeden stratejik DDD ile yolumuza devam edelim.<\/p>\n<h3>Strategic Domain Driven Design<\/h3>\n<p>DDD, stratejik olarak temel kavramlar \u00fcretmekte ve her bir proje s\u00fcrecinde bu kavramlara \u00f6zen g\u00f6sterilmesi gerekti\u011fini ifade etmektedir. \u015eimdi gelin bu kavramlar\u0131 tek tek inceleyelim.<\/p>\n<h6>Domain Model<\/h6>\n<p><div id=\"attachment_22125\" style=\"width: 310px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-22125\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-300x264.jpg\" alt=\"Domain Driven Design - Stratejik ve Taktiksel Olarak Derinlemesine \u0130nceleme\" width=\"300\" height=\"264\" class=\"size-medium wp-image-22125\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-300x264.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme.jpg 556w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-22125\" class=\"wp-caption-text\">\u00d6rnek bir Domain Model<\/p><\/div><em>Domain Driven Design<\/em>, uygulaman\u0131n etki plan\u0131n\u0131 yans\u0131tacak bir diyagram olan Domain Model&#8217;in kullan\u0131lmas\u0131n\u0131 \u00f6nermektedir. Bir domain model, yap\u0131lacak yaz\u0131l\u0131m\u0131n etki alan\u0131n\u0131n(yani domain&#8217;inin) toplam  fikrini i\u00e7ermesi ve \u015f\u00f6yleee bak\u0131ld\u0131\u011f\u0131 zaman herkesin ilgili operasyona dair neyin ne anlama geldi\u011fini anlayaca\u011f\u0131 bir vaziyette olmas\u0131 gerekmektedir.<\/p>\n<p>Domain model i\u00e7inde t\u00fcm \u00f6zellik adlar\u0131na sahiptir ve genellikle, UML diyagramlar\u0131na nazaran resim ve g\u00f6rselle desteklenmektedir.<\/p>\n<p>Son olarak Eric Evans&#8217;a g\u00f6re domain model;<\/p>\n<blockquote><p>Domain Model, belirli bir diyagram de\u011fildir! Diyagram\u0131n iletmeyi ama\u00e7lad\u0131\u011f\u0131 fikirdir. Ve bu sadece alan uzman\u0131n\u0131n kafas\u0131ndaki bilgi de\u011fil, bu bilginin titiz bir \u015fekilde organize edilmi\u015f bir soyutlamas\u0131d\u0131r.<\/p><\/blockquote>\n<h6>Domain Expert<\/h6>\n<p>Bir yaz\u0131l\u0131mc\u0131ya u\u00e7ak trafi\u011fi y\u00f6nlendirme ile ilgili bir uygulama geli\u015ftirmesi s\u00f6ylense, ilgili yaz\u0131l\u0131mc\u0131n\u0131n konuya dair herhangi bir bilgisi olmaks\u0131z\u0131n(yani domain bilgisi olmadan) uygulama geli\u015ftirmesi pek m\u00fcmk\u00fcn olmayacakt\u0131r. Yaz\u0131l\u0131mc\u0131n\u0131n bu i\u015fi ger\u00e7ekle\u015ftirebilmesi i\u00e7in; u\u00e7ak, u\u00e7ak trafi\u011fi, nereye y\u00f6nlendirilece\u011fi, ne \u015fekilde y\u00f6nlendirilece\u011fi, i\u015fin mevzuat\u0131 vs. gibi t\u00fcrl\u00fc bilgilerin ayd\u0131nlat\u0131lmas\u0131 gerekmektedir. Peki bu konulara hakim olan kim var? Filanca ki\u015fi&#8230; Art\u0131k her kimse&#8230; \u0130\u015fte o filanca ki\u015fi i\u015fin uzman\u0131 ve yaz\u0131l\u0131m\u0131n geli\u015ftirilmesi i\u00e7in gerekli t\u00fcm teorik bilgilere sahiptir. Haliyle bu ki\u015fi olmaks\u0131z\u0131n yaz\u0131l\u0131m\u0131n geli\u015ftirilmesi pek m\u00fcmk\u00fcn de\u011fildir. Bu ki\u015fi art\u0131k bizim i\u00e7in Domain Expert&#8217;tir.<\/p>\n<h6>UBIQUITOUS Language<\/h6>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-300x207.png\" alt=\"Domain Driven Design - Stratejik ve Taktiksel Olarak Derinlemesine \u0130nceleme\" width=\"300\" height=\"207\" class=\"alignleft size-medium wp-image-22136\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-300x207.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme.png 590w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Telafuzu zor olan bu terim(yubikut\u0131s ya da \u00f6yle bi\u015fey) yaz\u0131l\u0131m ekibiyle, domain expert aras\u0131ndaki ortak ileti\u015fimi sa\u011flamakta, sa\u011flanmas\u0131 gerekti\u011fini ifade etmektedir. Domain expert&#8217;ler, alanlar\u0131na dair her ne kadar derin ve yeterli bilgiye sahip olsalar da yaz\u0131l\u0131m geli\u015ftirme hakk\u0131nda hi\u00e7bir \u015fey bilmiyor olabilirler. Ayn\u0131 \u015fey yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi bir yaz\u0131l\u0131m geli\u015ftirici i\u00e7in de ge\u00e7erli olabilir ve \u00e7al\u0131\u015f\u0131lacak alana dair herhangi bir bilgi s\u00f6z konusu olmayabilir. \u0130\u015fte b\u00f6yle bir durumda DDD yaz\u0131l\u0131m geli\u015ftiricisi ile domain expert&#8217;ler aras\u0131nda her iki taraf\u0131nda rahat anla\u015fabilmesi i\u00e7in ortak dil bulunmas\u0131n\u0131 \u00f6nermektedir. Hatta bu bir tek domain expert ile geli\u015ftiricilerden ziyade projedeki di\u011fer t\u00fcm \u00e7al\u0131\u015fanlar i\u00e7inde ge\u00e7erli olabilecek \u015fekilde anla\u015f\u0131labilir bir dil olmas\u0131n\u0131 savunmaktad\u0131r. Evet, bu dili geli\u015ftirmek kolay de\u011fildir. Zaman alabilir amma velakin son derece gerekli bir u\u011fra\u015f oldu\u011fu a\u015fikard\u0131r. Zaten sizler onlarca kez, bu \u015fekilde ortak bir dil geli\u015ftirilmedi\u011fi durumlar i\u00e7in projelerde anla\u015fmazl\u0131klar\u0131n \u00e7\u0131kt\u0131\u011f\u0131na ve hatta ayn\u0131 \u015feyin farkl\u0131 kelimelerle anlat\u0131lmaya \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131ndan tart\u0131\u015fmalar\u0131n l\u00fczumsuz yere y\u00fckseldi\u011fine onlarca kez \u015fahit olmu\u015fsunuzdur kanaatindeyim. Haliyle bu do\u011fruyu illa ki DDD&#8217;nin s\u00f6ylemesine gerek olmasa da akl\u0131n yolu bir oldu\u011fu i\u00e7in DDD&#8217;de bunu kay\u0131ts\u0131z \u015farts\u0131z olmas\u0131 gereken bir durum olarak ortaya koymaktad\u0131r.<\/p>\n<p><strong><em>Peki Uniquitous Language&#8217;i koda nas\u0131l yans\u0131taca\u011f\u0131z?<\/em><\/strong><br \/>\nUbiquitous language&#8217;in \u00f6nerdi\u011fi ortak dilin geli\u015ftirilmesi ister istemez domain model&#8217;e yans\u0131yacakt\u0131r. \u00c7\u00fcnk\u00fc domain model, yap\u0131lacak i\u015fin omurgas\u0131d\u0131r. Haliyle otomatik olarak bu ortak dil koda yans\u0131m\u0131\u015f olacakt\u0131r. Zaten ortak dil kullanman\u0131n en b\u00fcy\u00fck avantaj\u0131 bu dilin tekrarl\u0131 kullan\u0131m\u0131nda dilin zay\u0131f y\u00f6nlerini belirlememizi sa\u011flamas\u0131d\u0131r. Bu durumda domain model h\u0131zl\u0131 bir \u015fekilde d\u00fczeltme yapabilmemizi sa\u011flayacak ve b\u00f6ylece ortak dilde bir \u015fey de\u011fi\u015firse bu domain model arac\u0131l\u0131\u011f\u0131yla do\u011frudan kod \u00fczerinde de de\u011fi\u015fikli\u011fe sebebiyet vermi\u015f olacakt\u0131r.<\/p>\n<p>Son olarak ortak dilin neden elzem oldu\u011funu ortaya koyabilmek i\u00e7in Bar\u0131\u015f Velio\u011flu&#8217;nun makalesindeki \u00f6rne\u011fi a\u015fa\u011f\u0131da al\u0131nt\u0131l\u0131yorum:<\/p>\n<blockquote><p>&#8230;dolay\u0131s\u0131yla ekip ya da firma i\u00e7erisinde isimlendirme konusunda tutarl\u0131l\u0131k g\u00f6stermek bir yana, yaz\u0131l\u0131mc\u0131lar\u0131n kendileriyle bile \u00e7eli\u015ftikleri durumlar olur. Bazen Delete s\u00f6zc\u00fc\u011f\u00fcn\u00fc kullan\u0131rken, bazen Remove s\u00f6zc\u00fc\u011f\u00fcn\u00fc kullanmaya karar verirler ve sordu\u011funuzda nedenini kendileri bile bilmez ya da hat\u0131rlamazlar&#8230;<\/p><\/blockquote>\n<p>\ud83d\ude42 Evet, bu g\u00fczel izahatten sonra bir projedeki de\u011fil farkl\u0131 payda\u015flar\u0131n ileti\u015fimi i\u00e7in ayn\u0131 i\u015fi yapan geli\u015ftiricilerin bile kendi aralar\u0131nda ortak bir terminolojiyi benimsemeleri kar\u0131\u015f\u0131kl\u0131l\u0131\u011f\u0131 engellemek i\u00e7in olduk\u00e7a \u00f6nem arz etmektedir.<\/p>\n<h6>Bounded Context<\/h6>\n<blockquote><p><em style=\"color:blue;\">Domain Driven Design tasar\u0131m\u0131ndaki en merkezi prensip Bounded Context&#8217;tir.<\/em><\/p><\/blockquote>\n<p>Bounded Context, birbirlerinden ayr\u0131lm\u0131\u015f ve s\u0131n\u0131rlar\u0131 belirlenmi\u015f yap\u0131lanmalard\u0131r. Esas\u0131nda bu i\u00e7eri\u011fimizin ba\u015flang\u0131\u00e7 paragraf\u0131nda belirtilen alt k\u0131r\u0131l\u0131mlardaki her bir ana k\u0131r\u0131l\u0131m bir Bounded Context&#8217;e kar\u015f\u0131l\u0131k gelmektedir. Bounded Context&#8217;leri mikro servis mimarilerdeki her bir servise kar\u015f\u0131l\u0131k gelen projeler\/microservis olarak da d\u00fc\u015fenebilirsiniz. Di\u011fer servisler olmadan, onlara ba\u011fl\u0131 olmaks\u0131z\u0131n geli\u015ftirilebilen, \u00e7al\u0131\u015ft\u0131r\u0131labilen, ba\u011f\u0131ms\u0131z otonom birimlerdir.<\/p>\n<p>\u00d6rnek vermemiz gerekirse; Amazon&#8217;da \u00fcr\u00fcnlerin aran\u0131p listelendi\u011fi yer, al\u0131\u015fveri\u015f sepeti, sat\u0131n alma i\u015flevleri vs. ayr\u0131 ayr\u0131 bounded context&#8217;tir. Bu i\u015flevlerin her biri di\u011feri olmadan tek ba\u015f\u0131na geli\u015ftirilebilir.<\/p>\n<p><strong><em>Peki Bounded Context&#8217;ler neye g\u00f6re belirlenir?<\/em><\/strong><br \/>\nBounded context&#8217;leri belirleyebilmek san\u0131ld\u0131\u011f\u0131 kadar kolay bir i\u015f de\u011fildir. Bunun i\u00e7in sezgisel olarak a\u015fa\u011f\u0131daki durumlara dikkat edilmesi \u00f6nerilmektedir:<\/p>\n<ul>\n<li>Domain hakk\u0131nda konu\u015furken, konu\u015fulan dile p\u00fcrdikkat kesilmek. Zaman zaman benzer, hatta ayn\u0131 kelimeler farkl\u0131 anlamlar ifade etmeye ba\u015flayabilir. Dilin tam bu farkl\u0131la\u015fmaya ba\u015flad\u0131\u011f\u0131 noktalar, bize farkl\u0131 s\u0131n\u0131rlar i\u00e7erisinde bulundu\u011fumuzu i\u015faret ediyor olabilir.<\/li>\n<li>Hangi seviyede transactional tutarl\u0131l\u0131\u011fa ihtiya\u00e7 oldu\u011funu g\u00f6zlemlemek. <\/li>\n<li>Yap\u0131lacak i\u015fin altyap\u0131s\u0131na g\u00f6re de\u011fil, i\u015f mant\u0131\u011f\u0131na g\u00f6re belirlenmelidir.<\/li>\n<\/ul>\n<blockquote><p><em style=\"color:orange;\">Domain Driven Design ile \u00e7al\u0131\u015fmak heuristic(sezgisel) olabilmeyi gerektirir.<\/em><\/p><\/blockquote>\n<p>Bounded context&#8217;ler;<\/p>\n<ul>\n<li>Kendi i\u00e7lerinde tutarl\u0131 ve b\u00fct\u00fcnd\u00fcr.<\/li>\n<li>Pek istenmese de belirli kurallar \u00e7er\u00e7evesinde birbirleriyle ileti\u015fim kurabilirler.<\/li>\n<\/ul>\n<h6>Context MAPPING<\/h6>\n<p>Bounded context&#8217;lerin kendi aralar\u0131ndaki ileti\u015fim mimarisine dayal\u0131 birbirleriyle olan kesi\u015fim noktalar\u0131n\u0131 izah edebilmeye context mapping denmektedir. Yani bir ba\u015fka deyi\u015fle context mapping, bounded context&#8217;ler ile bunlardan sorumlu ekipler aras\u0131ndaki ili\u015fkiyi belirlemenize olanak sa\u011flayan ara\u00e7t\u0131r. Buna bir \u00f6rnek vermemiz gerekirse e\u011fer; sipari\u015fler tablosunda(bounded context) m\u00fc\u015fteri numaras\u0131n\u0131n olmas\u0131 amma velakin m\u00fc\u015fteri tablosunda(bounded context) sipari\u015fe dair herhangi bir\u015feyin olmamas\u0131 yani bu s\u0131n\u0131rlar\u0131n ayarlanmas\u0131 bir Context Mapping&#8217;dir.<\/p>\n<h6>Clean &#8211; Readable Code<\/h6>\n<p>Kod in\u015fa edilirken domainin amac\u0131n\u0131 yans\u0131tacak \u015fekilde in\u015fa edilmelidir. Burada dikkat edilmesi gereken yap\u0131lara verilen isimlerin ne kadar pratik ya da standart oldu\u011fu de\u011fil, uzun dahi olsa ne kadar yapt\u0131\u011f\u0131 i\u015fi iyi anlat\u0131yor olmas\u0131d\u0131r. Bu DDD&#8217;nin \u00f6nerisidir. Temiz koda gelirsek e\u011fer, zaten bu iyi bir yaz\u0131l\u0131m\u0131n temel gereksinimidir.<\/p>\n<p>Evet&#8230; DDD&#8217;nin stratejik a\u00e7\u0131dan daha fazla kavram\u0131 olsa da konuyu genel anlamda anlayabilmek i\u00e7in ana hat mahiyetinde yukar\u0131dakilerin yeterli oldu\u011fu kanaatindeyim. \u015eimdi ise olay\u0131 biraz daha prati\u011fe d\u00f6kelim ve DDD&#8217;yi taktiksel a\u00e7\u0131dan inceleyerek, bizlere pratikte neleri \u00f6nerdi\u011fini g\u00f6relim.<\/p>\n<h3>Tactical Domain Driven Design<\/h3>\n<h6>Entity<\/h6>\n<p>DDD&#8217;da \u00f6nemli bir kavram olan Entity, kendini di\u011fer nesnelere nazaran tekille\u015ftirebilmek i\u00e7in bir kimli\u011fe(Id) sahip olan nesnelerdir. Entity, \u00f6z\u00fcnde Entity Framework&#8217;den a\u015fina olundu\u011fu gibi yery\u00fcz\u00fcndeki herhangi bir \u015fey i\u00e7in modellenmi\u015f nesnelere kar\u015f\u0131l\u0131k gelmektedir. Bahsedilen kimlik ise bu nesnelerin her biri i\u00e7in yarat\u0131ld\u0131\u011f\u0131 s\u00fcre\u00e7ten itibaren di\u011ferlerinden ay\u0131rmam\u0131z\u0131 sa\u011flayan ve de\u011fi\u015fmeden ta\u015f\u0131nan Id de\u011feridir.<\/p>\n<blockquote><p><em style=\"color:purple;\">Entity nesnelerinin de\u011ferleri de\u011fi\u015ftirilebilir.<\/em><\/p><\/blockquote>\n<p>Genellikle bir entity tan\u0131mlan\u0131rken, uygulamadaki di\u011fer s\u0131n\u0131flardan fark\u0131n\u0131 yaratabilmek i\u00e7in &#8216;IEntity&#8217; yahut &#8216;BaseEntity&#8217; gibi bir aray\u00fcz yahut s\u0131n\u0131f arac\u0131l\u0131\u011f\u0131yla a\u015fa\u011f\u0131dakine benzer bir i\u015faretleme ger\u00e7ekle\u015ftirilmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface IEntity { }\r\n    public class BaseEntity : IEntity\r\n    {\r\n        public int Id { get; set; }\r\n    }\r\n    public class Donanim : BaseEntity { }\r\n    public class Yazilim : BaseEntity { }\r\n<\/pre>\n<h6>Value Object<\/h6>\n<p>DDD prensibini kullanan veya kullanmayan \u00e7o\u011fu projede value object&#8217;ler fark\u0131nda olunsun ya da olunmas\u0131n kullan\u0131lan temel DDD yap\u0131 ta\u015flar\u0131d\u0131r diyebiliriz.<\/p>\n<p>Value object, herhangi bir kimlik(Id) de\u011feri olmayan ve b\u00f6ylece ayn\u0131 de\u011ferlere sahip iki value object nesnesinin de\u011fersel a\u00e7\u0131dan ayn\u0131 olarak kabul edilebilir olmas\u0131n\u0131 sa\u011flayan ve dolay\u0131s\u0131yla birbirlerinin yerine ge\u00e7ebilecekleri anlam\u0131na gelen bir nesnedir. \u0130\u015fte bu nedenle value object&#8217;ler her daim de\u011fi\u015fmez(immutable)dirler. <span style=\"font-size:9px;\">(bknz: <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-9-0-records-ile-immutable-datalar\/\" target=\"_blank\" rel=\"noopener\">Records \u0130le Immutable Datalar<\/a>)<\/span><\/p>\n<p>Value object&#8217;lerin de\u011fi\u015fmez olmas\u0131 operasyon s\u00fcre\u00e7lerini hem thread-safe hem de side effect(yan etki) durumlar\u0131na kar\u015f\u0131 korunakl\u0131 k\u0131lacakt\u0131r.<\/p>\n<p>Value object tan\u0131mlamalar\u0131nda &#8216;ValueObject&#8217; gibi bir isme sahip abstract class&#8217;la i\u015faretleme yap\u0131l\u0131r ve ilgili class i\u00e7erisinde birden fazla value object kar\u015f\u0131la\u015ft\u0131rmas\u0131n\u0131 yapacak olan a\u015fa\u011f\u0131daki metotlar bar\u0131nd\u0131r\u0131l\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic abstract class ValueObject\r\n{\r\n    protected static bool EqualOperator(ValueObject left, ValueObject right)\r\n    {\r\n        if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null))\r\n        {\r\n            return false;\r\n        }\r\n        return ReferenceEquals(left, null) || left.Equals(right);\r\n    }\r\n\r\n    protected static bool NotEqualOperator(ValueObject left, ValueObject right)\r\n    {\r\n        return !(EqualOperator(left, right));\r\n    }\r\n\r\n    protected abstract IEnumerable&lt;object&gt; GetEqualityComponents();\r\n\r\n    public override bool Equals(object obj)\r\n    {\r\n        if (obj == null || obj.GetType() != GetType())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        var other = (ValueObject)obj;\r\n\r\n        return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());\r\n    }\r\n\r\n    public override int GetHashCode()\r\n    {\r\n        return GetEqualityComponents()\r\n            .Select(x =&gt; x != null ? x.GetHashCode() : 0)\r\n            .Aggregate((x, y) =&gt; x ^ y);\r\n    }\r\n    \/\/ Other utility methods\r\n}\r\n<\/pre>\n<p>Bu metotlar value object&#8217;ler i\u00e7in Microsoft taraf\u0131ndan <a href=\"https:\/\/docs.microsoft.com\/tr-tr\/dotnet\/architecture\/microservices\/microservice-ddd-cqrs-patterns\/implement-value-objects\" rel=\"noopener\" target=\"_blank\">\u015furadaki<\/a> makalede de \u00f6nerilmektedir. Ne olduklar\u0131n\u0131 k\u0131saca izah etmemiz gerekirse e\u011fer;<\/p>\n<ul>\n<li><em><strong>EqualOperator<\/strong><\/em><br \/>\n\u0130ki value object&#8217;in birbirleriyle e\u015fit olduklar\u0131n\u0131 kontrol eder.\n<\/li>\n<li><em><strong>NotEqualOperator<\/strong><\/em><br \/>\n\u0130ki value object&#8217;in birbirleriyle e\u015fit olmad\u0131klar\u0131n\u0131 kontrol eder. <\/li>\n<li><em><strong>GetEqualityComponents<\/strong><\/em><br \/>\n\u0130ki value object kar\u015f\u0131la\u015ft\u0131r\u0131l\u0131rken i\u00e7lerindeki property&#8217;lerin de kar\u015f\u0131la\u015ft\u0131r\u0131lmas\u0131 gerekmektedir. Haliyle ilgili property&#8217;leri bu abstract metot \u00fczerinden g\u00f6nderip kar\u015f\u0131la\u015ft\u0131rma i\u015flemi ger\u00e7ekle\u015ftirilmektedir.\n<\/li>\n<li><em><strong>Equals<\/strong><\/em><br \/>\nVerilen value object&#8217;ler e\u015fit mi kontrol eder.\n<\/li>\n<\/ul>\n<p>Tasarlanan bu &#8216;ValueObject&#8217; abstract class&#8217;\u0131n\u0131 concrete value object&#8217;lere uygulad\u0131\u011f\u0131m\u0131zda a\u015fa\u011f\u0131daki gibi &#8216;GetEqualityComponents&#8217; metodunun implement edilip i\u00e7erideki property&#8217;lerin g\u00f6nderilmesi gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Address : ValueObject\r\n    {\r\n        public string City { get; set; }\r\n        public string Country { get; set; }\r\n        protected override IEnumerable&lt;object&gt; GetEqualityComponents()\r\n        {\r\n            yield return City;\r\n            yield return Country;\r\n        }\r\n    }\r\n<\/pre>\n<p><strong><em>Peki ORM kullan\u0131rken value object&#8217;leri bir entity i\u00e7erisinde nas\u0131l referans edece\u011fiz?<\/em><\/strong><br \/>\nBunun i\u00e7in kullan\u0131lan ORM&#8217;nin yap\u0131s\u0131 olduk\u00e7a \u00f6nemlidir. Misal olarak Entity Framework kullan\u0131yorsan\u0131z <a href=\"https:\/\/www.gencayyildiz.com\/blog\/entity-framework-core-owned-entities-and-table-splitting\/\" rel=\"noopener\" target=\"_blank\">Owned Entities and Table Splitting<\/a> value object&#8217;leri rahatl\u0131kla entity s\u0131n\u0131flar\u0131n\u0131zda referans edebilirsiniz.<\/p>\n<h6>Aggregate Root<\/h6>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-1-300x161.png\" alt=\"Domain Driven Design - Stratejik ve Taktiksel Olarak Derinlemesine \u0130nceleme\" width=\"300\" height=\"161\" class=\"alignleft size-medium wp-image-22180\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-1-300x161.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-1.png 422w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Entity ve Value Object&#8217;leri inceledikten sonra s\u0131radaki \u00f6nemli yap\u0131 Aggregate Root yap\u0131s\u0131d\u0131r. Aggregate root, birbiri ile alakal\u0131 farkl\u0131 entitylerin bir b\u00fct\u00fcnl\u00fck olu\u015fturabilmeleri, tutarl\u0131 olabilmeleri ve i\u015f kurallar\u0131n\u0131 ya da ak\u0131\u015flar\u0131n\u0131 ger\u00e7ekle\u015ftirebilmeleri i\u00e7in bir arada kullan\u0131lmas\u0131 durumudur.<\/p>\n<p>Aggregate root tan\u0131mlan\u0131rken, uygulamadaki di\u011fer s\u0131n\u0131flardan ay\u0131rt edebilmek i\u00e7in genellikle &#8216;IAggregateRoot&#8217; isminde bir aray\u00fczle i\u015faretleme ger\u00e7ekle\u015ftiririz. Benzer \u015fekilde aggregate root&#8217;lar \u00f6z\u00fcnde b\u00fct\u00fcnsel bir entity olacaklar\u0131ndan dolay\u0131 entity&#8217;leri temsil eden &#8216;IEntity&#8217; yahut &#8216;BaseEntity&#8217; yap\u0131lar\u0131yla i\u015faretlenmesi gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface IAggregateRoot { }\r\n\r\n    public class Address : ValueObject\r\n    {\r\n        public string City { get; set; }\r\n        public string Country { get; set; }\r\n        protected override IEnumerable&lt;object&gt; GetEqualityComponents()\r\n        {\r\n            yield return City;\r\n            yield return Country;\r\n        }\r\n    }\r\n\r\n    public class OrderItem : BaseEntity\r\n    {\r\n        public int Quantity { get; set; }\r\n        public long Price { get; set; }\r\n        public int ProductId { get; set; }\r\n    }\r\n\r\n    public class Order : BaseEntity, IAggregateRoot\r\n    {\r\n        public DateTime OrderDate { get; private set; }\r\n        public string Description { get; private set; }\r\n        public int BuyerId { get; private set; }\r\n        public string OrderStatus { get; private set; }\r\n        public Address Address { get; private set; }\r\n        public ICollection&lt;OrderItem&gt; OrderItems { get; private set; }\r\n\r\n        public Order(DateTime orderDate, string description, int buyerId, string orderStatus, Address address)\r\n        {\r\n            OrderDate = orderDate;\r\n            Description = description;\r\n            BuyerId = buyerId;\r\n            OrderStatus = orderStatus;\r\n            Address = address;\r\n            OrderItems = new List&lt;OrderItem&gt;();\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer, &#8216;Order&#8217;\u0131n &#8216;OrderItem&#8217;lar\u0131 y\u00f6netti\u011fini g\u00f6receksiniz. Haliyle aggregate root olan s\u0131n\u0131flarda bu y\u00f6netilen de\u011ferlerin validasyon kurallar\u0131 ba\u015fkas\u0131 d\u0131\u015far\u0131dan\/nesne \u00fczerinden m\u00fcdahale edemeyece\u011fi \u015fekilde aggregate root \u00fczerinden i\u015fletilebilmelidir. Bunun i\u00e7in t\u00fcm property&#8217;lerin set blo\u011fu private yap\u0131larak gerekli de\u011ferler k\u00e2h constructor&#8217;dan k\u00e2h farkl\u0131 bir metottan al\u0131narak kontroll\u00fc bir \u015fekilde taraf\u0131m\u0131zca set i\u015flemi ger\u00e7ekle\u015ftirilmelidir. Misal yukar\u0131daki \u00e7al\u0131\u015fmada de\u011ferler constructor&#8217;dan al\u0131nd\u0131\u011f\u0131 i\u00e7in ilgili validasyonlar a\u015fa\u011f\u0131daki gibi i\u015fletilebilir:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public Order(DateTime orderDate, string description, int buyerId, string orderStatus, Address address)\r\n        {\r\n            if (orderDate &lt; DateTime.Now)\r\n                throw new Exception(&quot;Order Date cannot be less than current time...&quot;);\r\n            if (description.Length &lt; 5)\r\n                throw new Exception(&quot;Description cannot be less than 5 characters&quot;);\r\n\r\n            \/*Di\u011fer Validasyon Kurallar\u0131*\/\r\n\r\n            OrderDate = orderDate;\r\n            Description = description;\r\n            BuyerId = buyerId;\r\n            OrderStatus = orderStatus;\r\n            Address = address;\r\n            OrderItems = new List&lt;OrderItem&gt;();\r\n        }\r\n<\/pre>\n<p>Esas\u0131nda ayn\u0131 durum a\u015fa\u011f\u0131daki &#8216;OrderItem&#8217;da \u00f6rneklendirildi\u011fi gibi normal entity&#8217;ler i\u00e7inde ge\u00e7erlidir diyebiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class OrderItem : BaseEntity\r\n    {\r\n        public int Quantity { get; private set; }\r\n        public long Price { get; private set; }\r\n        public int ProductId { get; private set; }\r\n\r\n        public OrderItem(int quantity, long price, int productId)\r\n        {\r\n            if (quantity &lt; 1)\r\n                throw new Exception(&quot;Quantity cannot be less than 1&quot;);\r\n            if (price &lt; 5)\r\n                throw new Exception(&quot;Price cannot be less than 5&quot;);\r\n\r\n            Quantity = quantity;\r\n            Price = price;\r\n            ProductId = productId;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yani burada \u015f\u00f6yle bir genellemeye varabiliriz ki: DDD; entity, value object ve aggregate root s\u0131n\u0131flar\u0131ndaki alanlara d\u0131\u015far\u0131dan set i\u015flemi yap\u0131lmas\u0131n\u0131 \u00f6nermemekte bilakis i\u00e7eriden kontroll\u00fc bir \u015fekilde bu i\u015flemin validasyon kontrolleriyle beraber ger\u00e7ekle\u015ftirilmesini tavsiye etmektedir.<\/p>\n<p><strong><em>Peki aggregate root olan &#8216;Order&#8217; nesnesine &#8216;OrderItem&#8217; entity&#8217;si nas\u0131l eklenecektir?<\/em><\/strong><br \/>\nBunun i\u00e7in &#8216;Order&#8217; i\u00e7erisinde d\u0131\u015far\u0131dan kontroll\u00fc bir \u015fekilde bu i\u015flemi y\u00fcr\u00fctecek bir fonksiyon yaz\u0131lmas\u0131 yeterlidir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Order : BaseEntity, IAggregateRoot\r\n    {\r\n        .\r\n        .\r\n        .\r\n        public void AddOrderItem(int quantity, long price, int productId)\r\n        {\r\n            OrderItems.Add(new(quantity, price, productId));\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer &#8216;AddOrderItem&#8217;a verilen parametreler e\u015fli\u011finde bir &#8216;OrderItem&#8217; nesnesi \u00fcretilmekte ve bu &#8216;OrderItems&#8217; koleksiyonuna verilmektedir. &#8216;OrderItem&#8217; gerekli validasyonlar\u0131 constructor&#8217;\u0131nda i\u015fletti\u011fi i\u00e7in i\u015f kurallar\u0131 d\u0131\u015f\u0131nda kalan herhangi bir veri s\u00f6z konusu oldu\u011fu durumda exception f\u0131rlatacak ve b\u00f6ylece tutarl\u0131l\u0131k sa\u011flanm\u0131\u015f olacakt\u0131r.<\/p>\n<p>\u015eimdi t\u00fcm bunlar\u0131n d\u0131\u015f\u0131nda aggregate root&#8217;lar i\u00e7in iki \u00f6nemli k\u0131s\u0131tlama mevcuttur:<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-2-300x257.png\" alt=\"Domain Driven Design - Stratejik ve Taktiksel Olarak Derinlemesine \u0130nceleme\" width=\"300\" height=\"257\" class=\"alignleft size-medium wp-image-22196\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-2-300x257.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/07\/Domain-Driven-Design-Stratejik-ve-Taktiksel-Olarak-Derinlemesine-Inceleme-2.png 537w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<ul>\n<li>Bunlardan ilki ve en \u00f6nemlisi, DDD&#8217;de bir aggregate root bir ba\u015fka aggregate root&#8217;ta ki entity ile ileti\u015fime ge\u00e7mez, ge\u00e7memelidir ve onlar\u0131n referans\u0131n\u0131 i\u00e7ermez, i\u00e7ermemelidir! Aggregate root&#8217;lar sadece kendi aralar\u0131nda yani birbirleriyle ileti\u015fim kurabilir, kurmal\u0131d\u0131r.<\/li>\n<li>Bir di\u011fer k\u0131s\u0131tlama ise uygulamalardaki repository s\u0131n\u0131flar\u0131 sade ve sadece aggregate root class&#8217;lar\u0131 i\u00e7in olu\u015fturulmal\u0131d\u0131r!<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h6>Layered Architecture<\/h6>\n<p>Domain Driven Design, geli\u015ftirme s\u00fcre\u00e7leri i\u00e7in herhangi bir teknolojik veya mimarisel se\u00e7im yapmaktan ziyade problemin net bir \u015fekilde tan\u0131mlanabilmesine yard\u0131mc\u0131 olmakta ve uygulamay\u0131 geli\u015ftiren t\u00fcm payda\u015flar\u0131n aras\u0131nda ortak bir dil(ubiquitous language) geli\u015ftirilmesini \u00f6ncelik olarak sunmaktad\u0131r. Bu mant\u0131kla yola \u00e7\u0131karsak e\u011fer DDD, projeye herhangi bir mimarisel yakla\u015f\u0131m\u0131 dayatmamakta, sadece yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi teknik olarak domain katman\u0131n\u0131n nas\u0131l tasarlanaca\u011f\u0131n\u0131 anlatmaktad\u0131r. Bu kabulden sonra hangi yakla\u015f\u0131m\u0131n ve mimarinin kullan\u0131laca\u011f\u0131 biz geli\u015ftiricilere ve projenin payda\u015flar\u0131n\u0131n ortak karar\u0131na kalm\u0131\u015ft\u0131r.<\/p>\n<p>Bu y\u00fczden DDD felsefesinde \u00f6nerilebilecek iki mimarisel yakla\u015f\u0131m\u0131 sizlere sunarak konuyu daha fazla uzatmadan noktalamak isterim.<\/p>\n<ul>\n<li><strong><em>Onion Architecture<\/em><\/strong><br \/>\nBu mimariye dair taraf\u0131mca klavyeye al\u0131nm\u0131\u015f <a href=\"https:\/\/www.gencayyildiz.com\/blog\/nedir-bu-onion-architecture-tam-teferruatli-inceleyelim\/\" rel=\"noopener\" target=\"_blank\">Nedir Bu Onion Architecture? Tam Teferruatl\u0131 \u0130nceleyelim<\/a> ve <a href=\"https:\/\/www.gencayyildiz.com\/blog\/onion-architectureda-cqrs-mediatr-pattern-automapper-fluent-validation\/\" rel=\"noopener\" target=\"_blank\">Onion Architecture\u2019da CQRS + MediatR Pattern + AutoMapper + Fluent Validation<\/a> ba\u015fl\u0131kl\u0131 makalelere g\u00f6z atabilirsiniz.\n<\/li>\n<li><strong><em>Hexagonal Architecture<\/em><\/strong><\/li>\n<p>Yak\u0131n zamanda bu konuya dair i\u00e7erik tasar\u0131m\u0131m bulunmaktad\u0131r. Haliyle konuya dair bir i\u00e7erik yazana kadar hep beraber farkl\u0131 kaynaklardan ara\u015ft\u0131rmaya, okumaya ve g\u00f6z atmaya devam \ud83d\ude42\n<\/ul>\n<p>Ve geldik sona&#8230; \ud83d\ude42 Teorik ve pratik olarak uzun soluklu bu i\u00e7eri\u011fe okuyarak e\u015flik etti\u011finiz i\u00e7in te\u015fekk\u00fcr ederim. Bundan sonraki DDD ile birlikte Microservice yap\u0131lanmalar\u0131na dair temaslar\u0131m\u0131z olacak konulara zengin bir temel te\u015fkil etmesini umarak yaz\u0131m\u0131z\u0131 burada noktal\u0131yorum.<\/p>\n<p>\u0130lgilenenlerin bol bol faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<div style=\"font-size:11px;line-height: 1.7;\">\n<u>Yararland\u0131\u011f\u0131m Kaynaklar<\/u><br \/>\nhttps:\/\/barisvelioglu.net\/domain-driven-design-kimdir-fe658cb0f6f0<br \/>\nhttps:\/\/www.codeproject.com\/Articles\/1020932\/Domain-Driven-Design-Reflecting-Business-in-the-Do<br \/>\nwww.youtube.com\/watch?v=_6msA3h2rFQ<br \/>\nhttps:\/\/vaadin.com\/learn\/tutorials\/ddd\/strategic_domain_driven_design<br \/>\nhttps:\/\/vaadin.com\/learn\/tutorials\/ddd\/tactical_domain_driven_design<br \/>\nhttps:\/\/vaadin.com\/learn\/tutorials\/ddd\/ddd_and_hexagonal<br \/>\nhttps:\/\/eksisozluk.com\/bounded-context&#8211;6710381\n<\/div>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Yeni bir projeye ba\u015flanaca\u011f\u0131 vakit projenin toplam net s\u00fcresini \u00f6ng\u00f6rebilmek i\u00e7in k\u00e2h sezgisel k\u00e2h tahmine dayal\u0131 alt k\u0131r\u0131l\u0131mlar olu\u015fturmaya \u00e7al\u0131\u015f\u0131r\u0131z. Bu k\u0131r\u0131l\u0131mlar e\u015fli\u011finde projenin anatomisini periyodik olarak daha hesaplanabilir hale getirerek, izafi a\u00e7\u0131dan&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":22222,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,153,3573],"tags":[4347,4339,4352,4341,4331,4348,4340,4342,4334,4333,4344,4351,4338,4346,4330,4335,4332,4349,4350,4144,4336,4343,4337,4345],"class_list":["post-22106","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-design-pattern","category-microservices","tag-aggregate-root","tag-bounded-context","tag-clean-readable-code","tag-context-mapping","tag-ddd","tag-ddd-aggregate-root","tag-ddd-bounded-context","tag-ddd-context-mapping","tag-ddd-domain-model","tag-ddd-domain-nedir","tag-ddd-entity","tag-ddd-layered-architecture","tag-ddd-ubiquitous-language","tag-ddd-value-object","tag-domain-driven-design","tag-domain-model","tag-eric-evans","tag-hexagonal-architecture","tag-layered-architecture","tag-onion-architecture","tag-strategic-domain-driven-design","tag-tactical-domain-driven-design","tag-ubiquitous-language","tag-value-object"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=22106"}],"version-history":[{"count":104,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22106\/revisions"}],"predecessor-version":[{"id":22221,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22106\/revisions\/22221"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/22222"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=22106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=22106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=22106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}