{"id":3404,"date":"2020-06-08T20:53:19","date_gmt":"2020-06-08T18:53:19","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=3404"},"modified":"2020-06-08T20:56:16","modified_gmt":"2020-06-08T18:56:16","slug":"secret-weapon-specification-pattern","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/secret-weapon-specification-pattern\/","title":{"rendered":"Gizli Silah: Specification Pattern"},"content":{"rendered":"<p>San\u0131r\u0131m <strong>specification pattern<\/strong>&#8216;\u0131 en son bir bu\u00e7uk y\u0131l \u00f6nce implemente etme ihtiyac\u0131m olmu\u015ftu. Amac\u0131m ise ilgili business domain&#8217;ini \u00e7ok fazla kompleks bir hale getirmeden ve domain bilgilerini duplicate etmeden, domain kurallar\u0131n\u0131 encapsulate ederek tekrar kullan\u0131labilir bir hale getirebilmekti.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2020\/06\/reusable-code.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-3418 lazyload\" data-src=\"\/wp-content\/uploads\/2020\/06\/reusable-code.jpg\" alt=\"\" width=\"864\" height=\"486\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/reusable-code.jpg 864w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/reusable-code-300x169.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/reusable-code-768x432.jpg 768w\" data-sizes=\"(max-width: 864px) 100vw, 864px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 864px; --smush-placeholder-aspect-ratio: 864\/486;\" \/><\/a><\/p>\n<p>Bir \u00e7o\u011fumuzun bildi\u011fi gibi specification pattern, yeni bir pattern de\u011fil. Son d\u00f6nemlerde ise bu pattern hakk\u0131nda farkl\u0131 d\u00fc\u015f\u00fcnceler ve tart\u0131\u015fmalara denk geldim. B\u00f6ylece bu pattern hakk\u0131nda bende bir \u015feyler yazmaya karar verdim. D\u00fcr\u00fcst olmak gerekirse gerekli g\u00f6rd\u00fc\u011f\u00fcm noktalarda bu pattern&#8217;\u0131 implemente etmek, benim i\u00e7in hala ho\u015f bir yakla\u015f\u0131m.<\/p>\n<p>Bu makale kapsam\u0131nda ise biraz specification pattern&#8217;dan bahsedip, en basit haliyle nas\u0131l implemente edebilece\u011fimizi g\u00f6stermeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<h2>Peki, nedir?<\/h2>\n<p>Specification pattern i\u00e7in en basit haliyle, istedi\u011fimiz domain bilgilerini\/kurallar\u0131n\u0131 encapsulate ederek tekrar kullan\u0131labilir par\u00e7alar olu\u015fturabilmemize olanak sa\u011flayan bir pattern&#8217;d\u0131r diyebiliriz.<\/p>\n<p>B\u00f6ylece uygulama i\u00e7erisinde ayn\u0131 domain kural\u0131na ait lambda expressions&#8217;lar\u0131 yaymak yerine, single responsibility prensibine ba\u011fl\u0131 kalarak ilgili t\u00fcm domain kurallar\u0131n\u0131 tek bir noktadan y\u00f6netip, tekrar kullan\u0131labilir bir hale getirebilmekteyiz.<\/p>\n<p>\u00d6rne\u011fin bir e-ticaret firmas\u0131n\u0131n \u00fcr\u00fcn domain&#8217;i i\u00e7erisinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z\u0131 ve sanal stok&#8217;lu \u00fcr\u00fcnleri listelemek istedi\u011fimizi d\u00fc\u015f\u00fcnelim.<\/p>\n<p>\u00dcr\u00fcn modeli a\u015fa\u011f\u0131daki gibi property&#8217;lere sahip olsun.<\/p>\n<pre class=\"lang:default decode:true\">public class Product\r\n{\r\n    public string Name { get; set; }\r\n    public bool IsVirtualStock { get; set; }\r\n    public bool IsFreeShipping { get; set; }\r\n}<\/pre>\n<p>Genelde bu gibi bir i\u015flemi, a\u015fa\u011f\u0131daki gibi bir lambda expression ile basit\u00e7e \u00e7\u00f6zebiliriz.<\/p>\n<pre class=\"lang:default decode:true\">List&lt;Product&gt; products = _dbContext.Products.Where(p =&gt; p.IsVirtualStock == true).ToList();<\/pre>\n<p>Bu noktaya kadar her \u015fey g\u00fczel.<\/p>\n<p>Daha sonra farkl\u0131 bir noktada ise \u00fcr\u00fcnlerin, sanal stok&#8217;lu olup olmad\u0131klar\u0131n\u0131 kontrol etme ihtiyac\u0131m\u0131z\u0131n oldu\u011funu d\u00fc\u015f\u00fcnelim. Elbette bu i\u015flemi de a\u015fa\u011f\u0131daki gibi basit\u00e7e \u00e7\u00f6zebiliriz.<\/p>\n<pre class=\"lang:default decode:true\">if(product.IsVirtualStock)\r\n{\r\n    ..\r\n}<\/pre>\n<p>Bu \u00f6rnekte oldu\u011fu gibi her yeni bir ihtiyac\u0131m\u0131zda, ilgili domain kural\u0131n\u0131 s\u00fcrekli farkl\u0131 noktalarda tekrar etmek zorunda kalaca\u011f\u0131z ve <strong>DRY<\/strong> prensibini ihlal edece\u011fiz. Ayr\u0131ca bu domain kural\u0131, birden fazla gereksinimin bir araya gelmesiyle de olu\u015fabilir.\u00a0 Bunun gibi bir araya geldi\u011finde \u00f6nem kazanan domain kurallar\u0131n\u0131 specification pattern yard\u0131m\u0131yla encapsulate edebilir, tek bir noktadan tekrar kullan\u0131labilir bir hale getirebiliriz.<\/p>\n<p>Birden fazla domain kural\u0131n\u0131n zincirleme olarak bir arada kullan\u0131ld\u0131\u011f\u0131 senaryolarda ise, lambda expression karma\u015fas\u0131 meydana gelebiliyor ve okunabilirli\u011fi de olduk\u00e7a d\u00fc\u015f\u00fcrebiliyor. Bu durumu da specification pattern yard\u0131m\u0131yla tersine \u00e7evirebilmek m\u00fcmk\u00fcn.<\/p>\n<h2>Haydi Kodlayal\u0131m!<\/h2>\n<p><a href=\"\/wp-content\/uploads\/2020\/06\/specification-diagram.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-3425 lazyload\" data-src=\"\/wp-content\/uploads\/2020\/06\/specification-diagram.jpg\" alt=\"\" width=\"968\" height=\"483\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-diagram.jpg 968w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-diagram-300x150.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-diagram-768x383.jpg 768w\" data-sizes=\"(max-width: 968px) 100vw, 968px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 968px; --smush-placeholder-aspect-ratio: 968\/483;\" \/><\/a><\/p>\n<p>\u00d6ncelikle a\u015fa\u011f\u0131daki gibi &#8220;<em>Specification<\/em>&#8221; isimli bir abstract class olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:default decode:true\">public abstract class Specification&lt;T&gt;\r\n{\r\n    public abstract Expression&lt;Func&lt;T, bool&gt;&gt; Expression();\r\n\r\n    public bool IsSatisfiedBy(T entity)\r\n    {\r\n        Func&lt;T, bool&gt; predicate = Expression().Compile();\r\n\r\n        return predicate(entity);\r\n    }\r\n}<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi specification pattern temelinde, bir domain model&#8217;inin istenilen domain kural\u0131na uyumlu olup olmad\u0131\u011f\u0131n\u0131 kontrol edebilmek i\u00e7in &#8220;<em>IsSatisfiedBy<\/em>&#8221; isimli bir method yer almaktad\u0131r.<\/p>\n<p>Concrete specification class&#8217;lar\u0131nda ise istedi\u011fimiz domain kurallar\u0131n\u0131, &#8220;<em>Expression<\/em>&#8221; method&#8217;u i\u00e7erisinde encapsulate edece\u011fiz.<\/p>\n<p>\u015eimdi sanal stoklu \u00fcr\u00fcn specification&#8217;\u0131n\u0131 a\u015fa\u011f\u0131daki gibi olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:default decode:true\">public class VirtualStockSpecification : Specification&lt;Product&gt;\r\n{\r\n    public override Expression&lt;Func&lt;Product, bool&gt;&gt; Expression()\r\n    {\r\n        return p =&gt; p.IsVirtualStock == true;\r\n    }\r\n}<\/pre>\n<p>Hepsi bu kadar.<\/p>\n<p>Olu\u015fturmu\u015f oldu\u011fumuz bu specification&#8217;\u0131 ister bir query i\u015flemi s\u0131ras\u0131nda, istersek de bir validation i\u015flemi s\u0131ras\u0131nda kullanabiliriz.<\/p>\n<p>\u00d6rne\u011fin repository i\u00e7erisinden geriye bir <strong>IQueryable<\/strong> d\u00f6nmek yerine, a\u015fa\u011f\u0131daki gibi specification kabul edebilir bir hale getirebiliriz.<\/p>\n<pre class=\"lang:default decode:true\">public class ProductRepository\r\n{\r\n    private readonly DbContext _dbContext;\r\n\r\n    public ProductRepository(DbContext dbContext)\r\n    {\r\n        _dbContext = dbContext;\r\n    }\r\n\r\n    public IEnumerable&lt;Product&gt; Filter(Specification&lt;Product&gt; specification)\r\n    {\r\n        return _dbContext.Products.Where(specification.Expression()).ToList();\r\n    }\r\n}<\/pre>\n<p>Ard\u0131ndan a\u015fa\u011f\u0131daki gibi farkl\u0131 ama\u00e7larla specification&#8217;\u0131 kullanabiliriz.<\/p>\n<pre class=\"lang:default decode:true\">public class ProductService\r\n{\r\n    private readonly ProductRepository _productRepository;\r\n\r\n    public ProductService(ProductRepository productRepository)\r\n    {\r\n        _productRepository = productRepository;\r\n    }\r\n\r\n    public List&lt;ProductDTO&gt; GetProducts()\r\n    {\r\n        List&lt;Product&gt; products = _productRepository.Filter(new VirtualStockSpecification()).ToList();\r\n\r\n        \/\/ ...\r\n    }\r\n\r\n    public ProductDTO AnotherMethod(int id)\r\n    {\r\n        Product product = _productRepository.Get(id);\r\n\r\n        var virtualStockSpecification = new VirtualStockSpecification();\r\n\r\n        if(virtualStockSpecification.IsSatisfiedBy(product))\r\n        {\r\n            \/\/ do something\r\n        }\r\n\r\n        \/\/ ...\r\n    }\r\n}<\/pre>\n<p>Yukar\u0131daki kod blo\u011fundan g\u00f6rebilece\u011fimiz \u00fczere, hem query i\u015flemi i\u00e7in hem de di\u011fer method i\u00e7erisinde validation i\u015flemi i\u00e7in &#8220;<em>VirtualStockSpecification<\/em>&#8221; \u0131 kulland\u0131k.<\/p>\n<p>Elbette specification&#8217;\u0131n kullan\u0131m\u0131 sadece bunlardan ibaret de\u011fil. Daha farkl\u0131 ihtiya\u00e7lar i\u00e7in specification&#8217;lar\u0131 zincirleme olarak &#8220;<strong>AND<\/strong>&#8220;, &#8220;<strong>OR<\/strong>&#8220;, &#8220;<strong>NOT<\/strong>&#8221; gibi yeteneklerle birle\u015ftirerek kullanabilmekte m\u00fcmk\u00fcn.<\/p>\n<p>Bu yakla\u015f\u0131m ise <strong>Composite Specification<\/strong> olarak adland\u0131r\u0131l\u0131yor. Bununla ilgili bir \u00f6rne\u011fe ise, <em><a href=\"https:\/\/en.wikipedia.org\/wiki\/Specification_pattern\" target=\"_blank\" rel=\"noopener noreferrer\">buradan<\/a> <\/em>eri\u015febilirsiniz.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Her ne kadar bu pattern hakk\u0131nda farkl\u0131 fikir ayr\u0131l\u0131klar\u0131 olsada, \u00e7o\u011fu zaman benim i\u00e7in hala kullan\u0131\u015fl\u0131 bir pattern. Specification&#8217;lar\u0131 kullanabilmek i\u00e7in olu\u015fturdu\u011fumuz base class&#8217;lar\u0131, projenin karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 artt\u0131ran unsurlar olarak g\u00f6rebilirsiniz. Fakat bize kazand\u0131rabilecek oldu\u011fu <strong>tekrar kullan\u0131labilirlik<\/strong> ve <strong>test edilebilirli\u011fi<\/strong> g\u00f6z \u00f6n\u00fcne ald\u0131\u011f\u0131m\u0131zda, \u00f6zellikle s\u00f6z konusu domain kurallar\u0131 ise, bence kabul edilebilir bir hale geliyor. Keza projenin maintenance&#8217;\u0131 \u00fczerinde de do\u011frudan bir etkisi oldu\u011funa inan\u0131yorum.<\/p>\n<p>Peki bu konuda sizin d\u00fc\u015f\u00fcnceleriniz nedir?<\/p>\n<h2>Referanslar<\/h2>\n<blockquote><p><em>https:\/\/en.wikipedia.org\/wiki\/Specification_pattern<\/em><br \/>\n<em>https:\/\/stackoverflow.com\/questions\/9709764\/specification-inside-linq-with-ef-4-3<\/em><\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>San\u0131r\u0131m specification pattern&#8216;\u0131 en son bir bu\u00e7uk y\u0131l \u00f6nce implemente etme ihtiyac\u0131m olmu\u015ftu. Amac\u0131m ise ilgili business domain&#8217;ini \u00e7ok fazla kompleks bir hale getirmeden ve domain bilgilerini duplicate etmeden, domain kurallar\u0131n\u0131 encapsulate ederek tekrar kullan\u0131labilir bir hale getirebilmekti. Bir \u00e7o\u011fumuzun bildi\u011fi gibi specification pattern, yeni&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/secret-weapon-specification-pattern\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">Gizli Silah: Specification Pattern<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":3443,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,505,68,47],"tags":[578,577],"class_list":["post-3404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-net-core","category-architectural","category-tasarim-kaliplari-design-patterns","tag-c-specification-pattern","tag-specification-pattern","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2020-06-08T18:53:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-06-08T18:56:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"Gizli Silah: Specification Pattern\",\"datePublished\":\"2020-06-08T18:53:19+00:00\",\"dateModified\":\"2020-06-08T18:56:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/\"},\"wordCount\":1435,\"commentCount\":8,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/specification-header-wall.jpg\",\"keywords\":[\"c# specification pattern\",\"specification pattern\"],\"articleSection\":[\".NET\",\".NET Core\",\"Architectural\",\"Tasar\u0131m Kal\u0131plar\u0131 (Design Patterns)\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/\",\"name\":\"Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/specification-header-wall.jpg\",\"datePublished\":\"2020-06-08T18:53:19+00:00\",\"dateModified\":\"2020-06-08T18:56:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/specification-header-wall.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/specification-header-wall.jpg\",\"width\":1200,\"height\":675},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/secret-weapon-specification-pattern\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Secret Weapon: Specification Pattern\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/","og_locale":"tr_TR","og_type":"article","og_title":"Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2020-06-08T18:53:19+00:00","article_modified_time":"2020-06-08T18:56:16+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"9 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"Gizli Silah: Specification Pattern","datePublished":"2020-06-08T18:53:19+00:00","dateModified":"2020-06-08T18:56:16+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/"},"wordCount":1435,"commentCount":8,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg","keywords":["c# specification pattern","specification pattern"],"articleSection":[".NET",".NET Core","Architectural","Tasar\u0131m Kal\u0131plar\u0131 (Design Patterns)"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/","url":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/","name":"Gizli Silah: Specification Pattern - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg","datePublished":"2020-06-08T18:53:19+00:00","dateModified":"2020-06-08T18:56:16+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/06\/specification-header-wall.jpg","width":1200,"height":675},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/secret-weapon-specification-pattern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Secret Weapon: Specification Pattern"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=3404"}],"version-history":[{"count":5,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3404\/revisions"}],"predecessor-version":[{"id":3454,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3404\/revisions\/3454"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/3443"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=3404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=3404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=3404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}