{"id":33819,"date":"2025-11-07T14:01:19","date_gmt":"2025-11-07T11:01:19","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/"},"modified":"2025-11-07T14:01:19","modified_gmt":"2025-11-07T11:01:19","slug":"tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/","title":{"rendered":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit"},"content":{"rendered":"<p><body><\/p>\n<p>Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.<\/p>\n<p>Uygulamalar b\u00fcy\u00fcd\u00fck\u00e7e ve i\u015flevsellikleri artt\u0131k\u00e7a, hemen her i\u015flem i\u00e7in bir t\u00fcr kay\u0131t tutma ihtiyac\u0131 do\u011far. Bir kullan\u0131c\u0131n\u0131n sepete \u00fcr\u00fcn eklemesi, bir \u00f6demenin onaylanmas\u0131, bir y\u00f6neticinin ayarlar\u0131 g\u00fcncellemesi gibi pek \u00e7ok senaryo, ilgili aktivitenin ne zaman, kim taraf\u0131ndan ve hangi parametrelerle ger\u00e7ekle\u015ftirildi\u011fini izlemeyi gerektirir. Ba\u015flang\u0131\u00e7ta bu gereklilik basit g\u00f6r\u00fcnse de, genellikle kontrols\u00fcz bir kod kirlili\u011fine yol a\u00e7ar. Geli\u015ftiriciler, &#8220;h\u0131zl\u0131 ve pratik&#8221; d\u00fc\u015f\u00fcncesiyle, i\u015f mant\u0131\u011f\u0131 kodlar\u0131n\u0131n i\u00e7ine do\u011frudan kay\u0131t (logging) \u00e7a\u011fr\u0131lar\u0131n\u0131 eklemeye ba\u015flarlar. \u00d6rne\u011fin, bir \u00fcr\u00fcn ekleme servisi \u015f\u00f6yle g\u00f6r\u00fcnebilir:<\/p>\n<pre><code>\nclass ProductService {\n    public void AddProduct(Product product) {\n        \/\/ \u00dcr\u00fcn ekleme i\u015f mant\u0131\u011f\u0131\n        productRepository.Add(product);\n        logger.LogInfo($\"\u00dcr\u00fcn '{product.Name}' eklendi.\");\n        notificationService.SendAdminNotification($\"Yeni \u00fcr\u00fcn eklendi: {product.Name}\");\n    }\n\n    public void UpdateProduct(Product product) {\n        \/\/ \u00dcr\u00fcn g\u00fcncelleme i\u015f mant\u0131\u011f\u0131\n        productRepository.Update(product);\n        logger.LogInfo($\"\u00dcr\u00fcn '{product.Name}' g\u00fcncellendi.\");\n        \/\/ Di\u011fer i\u015flemler...\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu yakla\u015f\u0131m\u0131n temel sorunlar\u0131 k\u0131sa s\u00fcrede kendini g\u00f6stermeye ba\u015flar. \u00d6ncelikle, <strong>kod tekrar\u0131 (DRY prensibinin ihlali)<\/strong> ka\u00e7\u0131n\u0131lmaz hale gelir. Her yeni metodun veya i\u015flevselli\u011fin eklenmesiyle birlikte, benzer kay\u0131t sat\u0131rlar\u0131 farkl\u0131 yerlerde tekrar tekrar yaz\u0131lmak zorunda kal\u0131r. \u00d6rne\u011fin, sadece \u00fcr\u00fcn ekleme de\u011fil, sipari\u015f olu\u015fturma, kullan\u0131c\u0131 kayd\u0131 gibi farkl\u0131 mod\u00fcllerin de kendi kay\u0131t mant\u0131klar\u0131 olacakt\u0131r. Bu durum, kod taban\u0131n\u0131n boyutunu gereksiz yere art\u0131r\u0131r ve okunabilirli\u011fi azalt\u0131r.<\/p>\n<p>\u0130kinci olarak, <strong>bak\u0131m zorlu\u011fu<\/strong> ortaya \u00e7\u0131kar. Kay\u0131t mekanizmas\u0131nda bir de\u011fi\u015fiklik yap\u0131lmas\u0131 gerekti\u011finde (\u00f6rne\u011fin, kay\u0131t format\u0131n\u0131n de\u011fi\u015ftirilmesi, farkl\u0131 bir kay\u0131t k\u00fct\u00fcphanesine ge\u00e7ilmesi veya kay\u0131t seviyelerinin ayarlanmas\u0131), bu de\u011fi\u015fikliklerin uygulaman\u0131n her yerine da\u011f\u0131lm\u0131\u015f y\u00fczlerce sat\u0131ra uygulanmas\u0131 gerekir. Bu da b\u00fcy\u00fck bir zaman kayb\u0131na ve hata yapma riskine yol a\u00e7ar. Ayr\u0131ca, i\u015f mant\u0131\u011f\u0131 kodunun i\u00e7ine g\u00f6m\u00fcl\u00fc olan kay\u0131t \u00e7a\u011fr\u0131lar\u0131, ger\u00e7ek i\u015f mant\u0131\u011f\u0131n\u0131n okunurlu\u011funu bozar ve kodun anla\u015f\u0131lmas\u0131n\u0131 zorla\u015ft\u0131r\u0131r.<\/p>\n<p>\u00dc\u00e7\u00fcnc\u00fc ve belki de en kritik sorun, <strong>test edilebilirli\u011fin azalmas\u0131d\u0131r<\/strong>. Kay\u0131t mant\u0131\u011f\u0131, i\u015f mant\u0131\u011f\u0131 ile s\u0131k\u0131 bir \u015fekilde birle\u015fti\u011finde, bir birim testi yazarken sadece i\u015f mant\u0131\u011f\u0131n\u0131 test etmek zorla\u015f\u0131r. Kay\u0131t \u00e7a\u011fr\u0131lar\u0131n\u0131 mock'lamak veya ger\u00e7ek bir kay\u0131t mekanizmas\u0131yla u\u011fra\u015fmak, testlerin karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 art\u0131r\u0131r ve test s\u00fcrecini yava\u015flat\u0131r. Bu durum, genellikle geli\u015ftiricilerin test yazmaktan ka\u00e7\u0131nmas\u0131na veya y\u00fczeysel testler yapmas\u0131na neden olur, bu da yaz\u0131l\u0131m kalitesini olumsuz etkiler.<\/p>\n<p>Son olarak, <strong>mimari esnekli\u011fin kaybolmas\u0131<\/strong> dikkat \u00e7eker. Kay\u0131t i\u015fleminin birincil i\u015flevden ayr\u0131lmas\u0131, asl\u0131nda \u00e7apraz kesen bir endi\u015fe (cross-cutting concern) olarak ele al\u0131nmal\u0131d\u0131r. Yani, uygulaman\u0131n bir\u00e7ok farkl\u0131 yerinde ihtiya\u00e7 duyulan ancak birincil i\u015f mant\u0131\u011f\u0131na do\u011frudan ait olmayan bir i\u015flevdir. Bu t\u00fcr endi\u015feleri i\u015f mant\u0131\u011f\u0131na kar\u0131\u015ft\u0131rmak, mod\u00fcllerin ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 art\u0131r\u0131r ve uygulaman\u0131n geni\u015fletilebilirli\u011fini, yeniden kullan\u0131labilirli\u011fini ve genel olarak temiz mimari prensiplerine uygunlu\u011funu zay\u0131flat\u0131r. Bu y\u00fczden, aktivite kay\u0131tlar\u0131n\u0131 ele al\u0131rken daha soyut ve esnek bir yakla\u015f\u0131ma ihtiyac\u0131m\u0131z var.<\/p>\n<h2>Decorator Pattern Nedir ve Temel Felsefesi Ne Anlama Gelir?<\/h2>\n<p>Decorator Pattern, yaz\u0131l\u0131m tasar\u0131m desenleri d\u00fcnyas\u0131nda \"yap\u0131sal desenler\" kategorisinde yer al\u0131r ve bir nesneye, mevcut yap\u0131s\u0131n\u0131 de\u011fi\u015ftirmeden yeni sorumluluklar dinamik olarak eklemenizi sa\u011flar. K\u0131sacas\u0131, bir nesnenin etraf\u0131na \"s\u00fcslemeler\" ekleyerek onun davran\u0131\u015f\u0131n\u0131 geni\u015fletme veya de\u011fi\u015ftirme prensibine dayan\u0131r. Bu desen, GoF (Gang of Four) taraf\u0131ndan tan\u0131mlanm\u0131\u015f 23 klasik tasar\u0131m deseninden biridir ve \u00f6zellikle esnekli\u011fin ve geni\u015fletilebilirli\u011fin kritik oldu\u011fu senaryolarda hayat kurtar\u0131c\u0131 olabilir.<\/p>\n<p>Peki, bu ne anlama geliyor? Geleneksel olarak, bir nesneye yeni \u00f6zellikler eklemek istedi\u011fimizde, ya o nesnenin s\u0131n\u0131f\u0131n\u0131 miras al\u0131r\u0131z (kal\u0131t\u0131m) ya da yeni bir s\u0131n\u0131f olu\u015fturup orijinal nesneyi i\u00e7inde tutar\u0131z (kompozisyon). Decorator Pattern, bu iki yakla\u015f\u0131m\u0131n avantajlar\u0131n\u0131 birle\u015ftirir: kal\u0131t\u0131m\u0131n esnekli\u011fini, kompozisyonun g\u00fcc\u00fcyle harmanlar. Temel felsefesi, bir nesnenin davran\u0131\u015f\u0131n\u0131 derleme zaman\u0131nda de\u011fil, \u00e7al\u0131\u015fma zaman\u0131nda de\u011fi\u015ftirebilme yetene\u011fidir.<\/p>\n<p>Bu desenin temel bile\u015fenlerini daha iyi anlayabilmek i\u00e7in, bir kahve sipari\u015fi \u00f6rne\u011fini d\u00fc\u015f\u00fcnebiliriz. Bir sade kahve (ConcreteComponent) sipari\u015f etti\u011finizde, \u00fczerine s\u00fct (ConcreteDecorator), krema (ConcreteDecorator) veya \u015furup (ConcreteDecorator) ekleyebilirsiniz. Her ekleme, kahvenin orijinal tad\u0131n\u0131 (i\u015flevini) de\u011fi\u015ftirmeden yeni bir \u00f6zellik (s\u00fcsleme) ekler ve toplam fiyat\u0131n\u0131 (davran\u0131\u015f\u0131n\u0131) art\u0131r\u0131r. \u0130\u015fte bu \u00f6rnek, Decorator Pattern'\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 m\u00fckemmel bir \u015fekilde \u00f6zetler.<\/p>\n<p>Decorator Pattern'\u0131n anahtar bile\u015fenleri \u015funlard\u0131r:<\/p>\n<ol>\n<li><strong>Component (Bile\u015fen):<\/strong> Hem dekore edilecek nesneler hem de dekorat\u00f6rler i\u00e7in ortak aray\u00fcz\u00fc veya soyut s\u0131n\u0131f\u0131 tan\u0131mlar. Bu, istemcinin (client) dekore edilmi\u015f veya dekore edilmemi\u015f nesneleri ayn\u0131 \u015fekilde ele almas\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, <code>IKahve<\/code> aray\u00fcz\u00fc.<\/li>\n<li><strong>ConcreteComponent (Somut Bile\u015fen):<\/strong> Component aray\u00fcz\u00fcn\u00fc uygulayan ve dekorat\u00f6rler taraf\u0131ndan dekore edilecek olan orijinal nesnedir. \u00d6rne\u011fin, <code>SadeKahve<\/code> s\u0131n\u0131f\u0131.<\/li>\n<li><strong>Decorator (Dekorat\u00f6r):<\/strong> Component aray\u00fcz\u00fcn\u00fc uygulayan ve bir Component referans\u0131n\u0131 tutan soyut bir s\u0131n\u0131ft\u0131r. Bu s\u0131n\u0131f\u0131n ana amac\u0131, dekore edilecek nesneye referans tutmak ve onun metodunu \u00e7a\u011f\u0131rmakt\u0131r. Bu, dekore edilen nesneye \"s\u00fcslemeler\" eklemek i\u00e7in bir iskelet g\u00f6revi g\u00f6r\u00fcr. \u00d6rne\u011fin, <code>KahveDekoratoru<\/code> soyut s\u0131n\u0131f\u0131.<\/li>\n<li><strong>ConcreteDecorator (Somut Dekorat\u00f6r):<\/strong> Decorator s\u0131n\u0131f\u0131n\u0131 miras alan ve belirli bir ek sorumluluk ekleyen somut s\u0131n\u0131flard\u0131r. Her somut dekorat\u00f6r, dekore edilen nesnenin i\u015flevselli\u011fini geni\u015fletir. \u00d6rne\u011fin, <code>SutluKahve<\/code>, <code>KremaliKahve<\/code> s\u0131n\u0131flar\u0131.<\/li>\n<\/ol>\n<div class=\"tip-box\">\n  Uzman \u0130pucu: Decorator Pattern, \u00f6zellikle SOLID prensiplerinden A\u00e7\u0131k\/Kapal\u0131 (Open\/Closed Principle) prensibini destekler. Mevcut kodu de\u011fi\u015ftirmeden yeni i\u015flevsellik eklemenizi sa\u011flar, bu da uygulaman\u0131z\u0131n daha esnek ve bak\u0131m\u0131 daha kolay olmas\u0131n\u0131 sa\u011flar.\n<\/div>\n<p>Bu desenin sa\u011flad\u0131\u011f\u0131 en b\u00fcy\u00fck avantajlardan biri, i\u015flevselli\u011fi kal\u0131t\u0131m hiyerar\u015fisinin kat\u0131l\u0131\u011f\u0131na ba\u011fl\u0131 kalmadan geni\u015fletebilmesidir. Kal\u0131t\u0131m ile, bir s\u0131n\u0131f\u0131n davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmek veya geni\u015fletmek istedi\u011finizde yeni bir alt s\u0131n\u0131f olu\u015fturman\u0131z gerekir. Bu, \u00e7ok fazla alt s\u0131n\u0131f\u0131n olu\u015fmas\u0131na ve hiyerar\u015finin karma\u015f\u0131kla\u015fmas\u0131na yol a\u00e7abilir. Decorator Pattern, bu sorunu kompozisyon ve aray\u00fczler arac\u0131l\u0131\u011f\u0131yla a\u015far, b\u00f6ylece daha mod\u00fcler ve dinamik bir yap\u0131 sunar. Bu temel anlay\u0131\u015fla, aktivite kay\u0131tlar\u0131n\u0131 nas\u0131l basitle\u015ftirebilece\u011fimize ge\u00e7ebiliriz.<\/p>\n<h2>Decorator Pattern ile Aktivite Kayd\u0131 Nas\u0131l D\u00f6n\u00fc\u015f\u00fcr? Ad\u0131m Ad\u0131m Bir Uygulama<\/h2>\n<p>Aktivite kay\u0131tlar\u0131n\u0131, i\u015f mant\u0131\u011f\u0131ndan ay\u0131rarak daha mod\u00fcler ve esnek bir yap\u0131ya kavu\u015fturmak i\u00e7in Decorator Pattern'\u0131 ad\u0131m ad\u0131m nas\u0131l uygulayaca\u011f\u0131m\u0131z\u0131 inceleyelim. Senaryomuz, bir e-ticaret uygulamas\u0131nda \"sipari\u015f i\u015fleme\" hizmetlerini kaydetmek olsun.<\/p>\n<h3>1. Temel Servis Aray\u00fcz\u00fcn\u00fc Tan\u0131mlama (Component)<\/h3>\n<p>\u00d6ncelikle, dekore edilecek olan temel i\u015flevselli\u011fi temsil eden bir aray\u00fcz tan\u0131mlamal\u0131y\u0131z. Bu, istemcilerin hem temel hizmeti hem de dekore edilmi\u015f hizmetleri ayn\u0131 \u015fekilde kullanabilmesini sa\u011flayacakt\u0131r.<\/p>\n<pre><code>\n\/\/ C# \u00f6rne\u011fi\npublic interface ISiparisServisi\n{\n    void SiparisOlustur(int userId, List<int> urunIdleri);\n    void SiparisGuncelle(int siparisId, string durum);\n    void SiparisIptalEt(int siparisId);\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu aray\u00fcz, sipari\u015flerle ilgili temel operasyonlar\u0131 tan\u0131mlar. Art\u0131k hangi somut s\u0131n\u0131f\u0131n bu aray\u00fcz\u00fc uygulad\u0131\u011f\u0131n\u0131 veya bu metodlar\u0131n ekstra bir \u00f6zelli\u011fi olup olmad\u0131\u011f\u0131n\u0131 dert etmeden, <code>ISiparisServisi<\/code> tipinde bir nesne ile \u00e7al\u0131\u015fabiliriz.<\/p>\n<h3>2. Somut Servis Uygulamas\u0131 (ConcreteComponent)<\/h3>\n<p>\u015eimdi, temel i\u015f mant\u0131\u011f\u0131n\u0131 i\u00e7eren ger\u00e7ek sipari\u015f hizmetini uygulayal\u0131m. Bu s\u0131n\u0131f, herhangi bir kay\u0131t veya ek i\u015flevsellik bar\u0131nd\u0131rmamal\u0131, sadece sipari\u015flerle ilgili \u00e7ekirdek i\u015fleri yapmal\u0131d\u0131r.<\/p>\n<pre><code>\npublic class GercekSiparisServisi : ISiparisServisi\n{\n    public void SiparisOlustur(int userId, List<int> urunIdleri)\n    {\n        Console.WriteLine($\"Kullan\u0131c\u0131 {userId} i\u00e7in sipari\u015f olu\u015fturuluyor, \u00fcr\u00fcnler: {string.Join(\", \", urunIdleri)}.\");\n        \/\/ Veritaban\u0131 i\u015flemleri, stok kontrol\u00fc vb.\n        Console.WriteLine(\"Sipari\u015f ba\u015far\u0131yla olu\u015fturuldu.\");\n    }\n\n    public void SiparisGuncelle(int siparisId, string durum)\n    {\n        Console.WriteLine($\"Sipari\u015f {siparisId} durumu '{durum}' olarak g\u00fcncelleniyor.\");\n        \/\/ Veritaban\u0131 g\u00fcncelleme i\u015flemleri\n        Console.WriteLine(\"Sipari\u015f durumu g\u00fcncellendi.\");\n    }\n\n    public void SiparisIptalEt(int siparisId)\n    {\n        Console.WriteLine($\"Sipari\u015f {siparisId} iptal ediliyor.\");\n        \/\/ Veritaban\u0131 i\u015flemleri, iade s\u00fcreci ba\u015flatma vb.\n        Console.WriteLine(\"Sipari\u015f iptal edildi.\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, bu s\u0131n\u0131f tamamen \"saf\" i\u015f mant\u0131\u011f\u0131 i\u00e7erir. Hi\u00e7bir kay\u0131t \u00e7a\u011fr\u0131s\u0131 veya bildirim mant\u0131\u011f\u0131 bulunmuyor. Bu, test edilebilirli\u011fini ve okunabilirli\u011fini art\u0131r\u0131yor.<\/p>\n<h3>3. Soyut Dekorat\u00f6r S\u0131n\u0131f\u0131n\u0131 Tan\u0131mlama (Decorator)<\/h3>\n<p>T\u00fcm dekorat\u00f6rler i\u00e7in temel bir yap\u0131 sa\u011flayacak olan soyut dekorat\u00f6r s\u0131n\u0131f\u0131n\u0131 olu\u015fturmal\u0131y\u0131z. Bu s\u0131n\u0131f, <code>ISiparisServisi<\/code> aray\u00fcz\u00fcn\u00fc uygulamal\u0131 ve dekore edilecek <code>ISiparisServisi<\/code> nesnesine bir referans tutmal\u0131d\u0131r.<\/p>\n<pre><code>\npublic abstract class SiparisServisiDekoratoru : ISiparisServisi\n{\n    protected ISiparisServisi _siparisServisi;\n\n    public SiparisServisiDekoratoru(ISiparisServisi siparisServisi)\n    {\n        _siparisServisi = siparisServisi;\n    }\n\n    \/\/ Her metodu varsay\u0131lan olarak temel servise y\u00f6nlendiriyoruz.\n    \/\/ Alt s\u0131n\u0131flar bu metodlar\u0131 override ederek ek i\u015flevsellik ekleyecekler.\n    public virtual void SiparisOlustur(int userId, List<int> urunIdleri)\n    {\n        _siparisServisi.SiparisOlustur(userId, urunIdleri);\n    }\n\n    public virtual void SiparisGuncelle(int siparisId, string durum)\n    {\n        _siparisServisi.SiparisGuncelle(siparisId, durum);\n    }\n\n    public virtual void SiparisIptalEt(int siparisId)\n    {\n        _siparisServisi.SiparisIptalEt(siparisId);\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Burada, <code>_siparisServisi<\/code> alan\u0131n\u0131 kullanarak temel servise eri\u015fim sa\u011fl\u0131yoruz. Metodlar <code>virtual<\/code> olarak i\u015faretlenmi\u015ftir, b\u00f6ylece alt s\u0131n\u0131flar (somut dekorat\u00f6rler) bunlar\u0131 ge\u00e7ersiz k\u0131larak kendi \u00f6zel davran\u0131\u015flar\u0131n\u0131 ekleyebilirler.<\/p>\n<h3>4. Kay\u0131t Dekorat\u00f6r\u00fcn\u00fc Uygulama (ConcreteDecorator)<\/h3>\n<p>\u015eimdi, as\u0131l amac\u0131m\u0131z olan aktivite kayd\u0131n\u0131 sa\u011flayan somut dekorat\u00f6r\u00fc olu\u015ftural\u0131m. Bu dekorat\u00f6r, <code>SiparisServisiDekoratoru<\/code> s\u0131n\u0131f\u0131n\u0131 miras alacak ve metodlar\u0131 ge\u00e7ersiz k\u0131larak ek kay\u0131t mant\u0131\u011f\u0131n\u0131 dahil edecektir.<\/p>\n<pre><code>\npublic class LoglamaSiparisServisiDekoratoru : SiparisServisiDekoratoru\n{\n    public LoglamaSiparisServisiDekoratoru(ISiparisServisi siparisServisi)\n        : base(siparisServisi)\n    {\n    }\n\n    public override void SiparisOlustur(int userId, List<int> urunIdleri)\n    {\n        Console.WriteLine($\"[LOG] Sipari\u015f olu\u015fturma talebi al\u0131nd\u0131. Kullan\u0131c\u0131 ID: {userId}\");\n        _siparisServisi.SiparisOlustur(userId, urunIdleri); \/\/ Temel i\u015flemi \u00e7a\u011f\u0131r\n        Console.WriteLine($\"[LOG] Sipari\u015f {userId} i\u00e7in ba\u015far\u0131yla olu\u015fturuldu.\");\n    }\n\n    public override void SiparisGuncelle(int siparisId, string durum)\n    {\n        Console.WriteLine($\"[LOG] Sipari\u015f {siparisId} i\u00e7in durum g\u00fcncelleme talebi al\u0131nd\u0131. Yeni Durum: {durum}\");\n        _siparisServisi.SiparisGuncelle(siparisId, durum); \/\/ Temel i\u015flemi \u00e7a\u011f\u0131r\n        Console.WriteLine($\"[LOG] Sipari\u015f {siparisId} durumu '{durum}' olarak g\u00fcncellendi.\");\n    }\n\n    public override void SiparisIptalEt(int siparisId)\n    {\n        Console.WriteLine($\"[LOG] Sipari\u015f {siparisId} i\u00e7in iptal talebi al\u0131nd\u0131.\");\n        _siparisServisi.SiparisIptalEt(siparisId); \/\/ Temel i\u015flemi \u00e7a\u011f\u0131r\n        Console.WriteLine($\"[LOG] Sipari\u015f {siparisId} ba\u015far\u0131yla iptal edildi.\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu dekorat\u00f6r, her bir metodun \u00f6ncesine ve sonras\u0131na kay\u0131t mant\u0131\u011f\u0131n\u0131 eklerken, temel i\u015fi <code>_siparisServisi.Siparis...()<\/code> \u00e7a\u011fr\u0131lar\u0131 ile ger\u00e7ekle\u015ftirmeye devam ediyor. Bu sayede kay\u0131t mant\u0131\u011f\u0131, i\u015f mant\u0131\u011f\u0131ndan tamamen ayr\u0131lm\u0131\u015f oluyor.<\/p>\n<h3>5. Kullan\u0131m ve Kompozisyon<\/h3>\n<p>Art\u0131k istemci kodu, hangi hizmeti kullanmak istedi\u011fini dinamik olarak se\u00e7ebilir. Kay\u0131t \u00f6zellikli bir servis mi istiyor? Sadece <code>LoglamaSiparisServisiDekoratoru<\/code> ile sarmalamas\u0131 yeterli.<\/p>\n<pre><code>\n\/\/ \u0130stemci taraf\u0131nda kullan\u0131m\npublic class Client\n{\n    public static void Main(string[] args)\n    {\n        \/\/ Temel sipari\u015f servisi\n        ISiparisServisi gercekServis = new GercekSiparisServisi();\n\n        \/\/ Kay\u0131t eklenmi\u015f sipari\u015f servisi\n        ISiparisServisi logluServis = new LoglamaSiparisServisiDekoratoru(gercekServis);\n\n        Console.WriteLine(\"--- Logsuz Servis Kullan\u0131m\u0131 ---\");\n        gercekServis.SiparisOlustur(101, new List<int> { 1, 2 });\n        gercekServis.SiparisGuncelle(500, \"Haz\u0131rlan\u0131yor\");\n        Console.WriteLine(\"-----------------------------\");\n\n        Console.WriteLine(\"--- Loglu Servis Kullan\u0131m\u0131 ---\");\n        logluServis.SiparisOlustur(102, new List<int> { 3, 4 });\n        logluServis.SiparisIptalEt(501);\n        Console.WriteLine(\"----------------------------\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00e7\u0131kt\u0131, her iki durumda da temel i\u015f mant\u0131\u011f\u0131n\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131, ancak yaln\u0131zca <code>logluServis<\/code> kullan\u0131ld\u0131\u011f\u0131nda kay\u0131t mesajlar\u0131n\u0131n g\u00f6r\u00fcnt\u00fclendi\u011fini g\u00f6sterecektir. Bu yap\u0131 sayesinde, uygulaman\u0131z\u0131n herhangi bir yerine kay\u0131t \u00f6zelli\u011fi eklemek istedi\u011finizde, mevcut kodunuzu (<code>GercekSiparisServisi<\/code>) de\u011fi\u015ftirmek zorunda kalmazs\u0131n\u0131z. Sadece yeni bir dekorat\u00f6r yarat\u0131r ve mevcut servisi onunla sarmalars\u0131n\u0131z. Bu, A\u00e7\u0131k\/Kapal\u0131 prensibine m\u00fckemmel bir uyum sa\u011flar ve aktivite kay\u0131tlar\u0131 gibi \u00e7apraz kesen endi\u015felerin y\u00f6netimini %70 veya daha fazla oranda basitle\u015ftirebilir.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryosu: Bir E-Ticaret Platformunda Sepet \u0130\u015flemlerini Kaydetme<\/h2>\n<p>Bir e-ticaret platformunun \"sepet\" mod\u00fcl\u00fc, kullan\u0131c\u0131 deneyiminin kalbi niteli\u011findedir. Kullan\u0131c\u0131n\u0131n \u00fcr\u00fcnleri sepete eklemesi, \u00e7\u0131karmas\u0131, miktar\u0131n\u0131 g\u00fcncellemesi veya sepeti bo\u015faltmas\u0131 gibi her i\u015flem kritik \u00f6neme sahiptir. Bu i\u015flemlerin do\u011fru bir \u015fekilde kaydedilmesi, hem hata ay\u0131klama (debugging) i\u00e7in hem de i\u015f analizi, kullan\u0131c\u0131 davran\u0131\u015f\u0131 takibi ve g\u00fcvenlik denetimleri i\u00e7in elzemdir. Ancak bu kadar \u00e7ok i\u015flemde kay\u0131t mant\u0131\u011f\u0131n\u0131 her yere serpi\u015ftirmek, az \u00f6nce bahsetti\u011fimiz \"tekrar eden kod kabusu\"nu yarat\u0131r.<\/p>\n<h3>Dekorat\u00f6r \u00d6ncesi Durum: Tekrarlayan ve Bak\u0131m\u0131 Zor Kod<\/h3>\n<p>Dekorat\u00f6r desenini kullanmadan \u00f6nce, bir e-ticaret uygulamas\u0131nda sepet i\u015flemleri \u015f\u00f6yle g\u00f6r\u00fcnebilirdi:<\/p>\n<pre><code>\n\/\/ Tekrarlayan kod \u00f6ncesi\npublic interface ISepetServisi\n{\n    void UrunEkle(string userId, string productId, int quantity);\n    void UrunCikar(string userId, string productId);\n    void MiktarGuncelle(string userId, string productId, int newQuantity);\n    void SepetiBosalt(string userId);\n}\n\npublic class SomutSepetServisi : ISepetServisi\n{\n    private readonly ILogger _logger;\n    private readonly ISepetRepository _sepetRepository;\n\n    public SomutSepetServisi(ILogger logger, ISepetRepository sepetRepository)\n    {\n        _logger = logger;\n        _sepetRepository = sepetRepository;\n    }\n\n    public void UrunEkle(string userId, string productId, int quantity)\n    {\n        _logger.LogInfo($\"[\u0130\u015flem Ba\u015flad\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} sepete ekliyor. Miktar: {quantity}.\");\n        _sepetRepository.AddProductToCart(userId, productId, quantity);\n        _logger.LogInfo($\"[\u0130\u015flem Tamamland\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} sepete ekledi.\");\n    }\n\n    public void UrunCikar(string userId, string productId)\n    {\n        _logger.LogInfo($\"[\u0130\u015flem Ba\u015flad\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} sepetten \u00e7\u0131kar\u0131yor.\");\n        _sepetRepository.RemoveProductFromCart(userId, productId);\n        _logger.LogInfo($\"[\u0130\u015flem Tamamland\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} sepetten \u00e7\u0131kard\u0131.\");\n    }\n\n    public void MiktarGuncelle(string userId, string productId, int newQuantity)\n    {\n        _logger.LogInfo($\"[\u0130\u015flem Ba\u015flad\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} miktar\u0131n\u0131 {newQuantity} olarak g\u00fcncelliyor.\");\n        _sepetRepository.UpdateProductQuantity(userId, productId, newQuantity);\n        _logger.LogInfo($\"[\u0130\u015flem Tamamland\u0131] Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} miktar\u0131n\u0131 g\u00fcncelledi.\");\n    }\n\n    public void SepetiBosalt(string userId)\n    {\n        _logger.LogInfo($\"[\u0130\u015flem Ba\u015flad\u0131] Kullan\u0131c\u0131 {userId} sepetini bo\u015falt\u0131yor.\");\n        _sepetRepository.ClearCart(userId);\n        _logger.LogInfo($\"[\u0130\u015flem Tamamland\u0131] Kullan\u0131c\u0131 {userId} sepetini bo\u015faltt\u0131.\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, her metodun i\u00e7inde kay\u0131t \u00e7a\u011fr\u0131lar\u0131n\u0131 (<code>_logger.LogInfo(...)<\/code>) g\u00f6rebilirsiniz. Bu, mod\u00fcl\u00fcn birincil sorumlulu\u011fu olan \"sepet i\u015flemlerini y\u00f6netme\" ile ikincil bir sorumluluk olan \"kay\u0131t tutma\"y\u0131 bir araya getiriyor. Sonu\u00e7 olarak:<\/p>\n<ul>\n<li>Her yeni sepet i\u015flemi i\u00e7in benzer kay\u0131t kodlar\u0131 tekrar tekrar yaz\u0131lmak zorunda kal\u0131yor.<\/li>\n<li>Kay\u0131t mekanizmas\u0131nda bir de\u011fi\u015fiklik yap\u0131lmas\u0131 gerekti\u011finde (\u00f6rne\u011fin, farkl\u0131 bir loglama k\u00fct\u00fcphanesine ge\u00e7i\u015f), <code>SomutSepetServisi<\/code> s\u0131n\u0131f\u0131n\u0131n her metodunun g\u00fcncellenmesi gerekiyor.<\/li>\n<li><code>SomutSepetServisi<\/code> s\u0131n\u0131f\u0131n\u0131n testleri, hem sepet i\u015f mant\u0131\u011f\u0131n\u0131 hem de kay\u0131t mant\u0131\u011f\u0131n\u0131 i\u00e7ermek zorunda kal\u0131yor, bu da testlerin karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 art\u0131r\u0131yor.<\/li>\n<li>Kod, sepet i\u015flevselli\u011fi ile kay\u0131t i\u015flevselli\u011fi aras\u0131nda s\u0131k\u0131 bir ba\u011f\u0131ml\u0131l\u0131\u011fa sahip oluyor.<\/li>\n<\/ul>\n<h3>Dekorat\u00f6r Sonras\u0131 Durum: Temiz, Geni\u015fletilebilir ve Bak\u0131m\u0131 Kolay Kod<\/h3>\n<p>Decorator Pattern kullanarak bu sorunlar\u0131 nas\u0131l \u00e7\u00f6zd\u00fc\u011f\u00fcm\u00fcze bakal\u0131m. \u0130lk olarak, <code>ISepetServisi<\/code> aray\u00fcz\u00fcm\u00fcz ayn\u0131 kal\u0131r.<\/p>\n<pre><code>\n\/\/ Decorator sonras\u0131 - ISepetServisi ayn\u0131 kal\u0131r\npublic interface ISepetServisi\n{\n    void UrunEkle(string userId, string productId, int quantity);\n    void UrunCikar(string userId, string productId);\n    void MiktarGuncelle(string userId, string productId, int newQuantity);\n    void SepetiBosalt(string userId);\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi, <code>SomutSepetServisi<\/code> s\u0131n\u0131f\u0131n\u0131 kay\u0131t mant\u0131\u011f\u0131ndan ar\u0131nd\u0131r\u0131yoruz. Sadece kendi temel i\u015flevselli\u011fine odaklan\u0131yor:<\/p>\n<pre><code>\n\/\/ Decorator sonras\u0131 - Temiz SomutSepetServisi\npublic class SomutSepetServisi : ISepetServisi\n{\n    private readonly ISepetRepository _sepetRepository;\n\n    public SomutSepetServisi(ISepetRepository sepetRepository)\n    {\n        _sepetRepository = sepetRepository;\n    }\n\n    public void UrunEkle(string userId, string productId, int quantity)\n    {\n        Console.WriteLine($\"Sepet: Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} ({quantity} adet) sepete ekliyor.\");\n        _sepetRepository.AddProductToCart(userId, productId, quantity);\n    }\n\n    public void UrunCikar(string userId, string productId)\n    {\n        Console.WriteLine($\"Sepet: Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} sepetten \u00e7\u0131kar\u0131yor.\");\n        _sepetRepository.RemoveProductFromCart(userId, productId);\n    }\n\n    public void MiktarGuncelle(string userId, string productId, int newQuantity)\n    {\n        Console.WriteLine($\"Sepet: Kullan\u0131c\u0131 {userId}, \u00fcr\u00fcn\u00fc {productId} miktar\u0131n\u0131 {newQuantity} olarak g\u00fcncelliyor.\");\n        _sepetRepository.UpdateProductQuantity(userId, productId, newQuantity);\n    }\n\n    public void SepetiBosalt(string userId)\n    {\n        Console.WriteLine($\"Sepet: Kullan\u0131c\u0131 {userId} sepetini bo\u015falt\u0131yor.\");\n        _sepetRepository.ClearCart(userId);\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, bu s\u0131n\u0131f art\u0131k sadece sepet i\u015flemlerine odaklanm\u0131\u015f durumda. Kay\u0131t \u00e7a\u011fr\u0131lar\u0131 tamamen d\u0131\u015far\u0131 ta\u015f\u0131nd\u0131. \u015eimdi bir <code>SepetServisiDekoratoru<\/code> soyut s\u0131n\u0131f\u0131 ve bir <code>LoglamaSepetServisiDekoratoru<\/code> somut s\u0131n\u0131f\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code>\n\/\/ Soyut Sepet Servisi Dekoratoru\npublic abstract class SepetServisiDekoratoru : ISepetServisi\n{\n    protected ISepetServisi _sepetServisi;\n\n    public SepetServisiDekoratoru(ISepetServisi sepetServisi)\n    {\n        _sepetServisi = sepetServisi;\n    }\n\n    public virtual void UrunEkle(string userId, string productId, int quantity) => _sepetServisi.UrunEkle(userId, productId, quantity);\n    public virtual void UrunCikar(string userId, string productId) => _sepetServisi.UrunCikar(userId, productId);\n    public virtual void MiktarGuncelle(string userId, string productId, int newQuantity) => _sepetServisi.MiktarGuncelle(userId, productId, newQuantity);\n    public virtual void SepetiBosalt(string userId) => _sepetServisi.SepetiBosalt(userId);\n}\n\n\/\/ Loglama Sepet Servisi Dekoratoru\npublic class LoglamaSepetServisiDekoratoru : SepetServisiDekoratoru\n{\n    private readonly ILogger _logger; \/\/ Ger\u00e7ek bir logger ba\u011f\u0131ml\u0131l\u0131\u011f\u0131\n\n    public LoglamaSepetServisiDekoratoru(ISepetServisi sepetServisi, ILogger logger)\n        : base(sepetServisi)\n    {\n        _logger = logger;\n    }\n\n    public override void UrunEkle(string userId, string productId, int quantity)\n    {\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} \u00fcr\u00fcn\u00fc {productId} sepete ekledi. Miktar: {quantity}.\");\n        _sepetServisi.UrunEkle(userId, productId, quantity); \/\/ Temel i\u015flemi \u00e7a\u011f\u0131r\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} i\u00e7in sepet g\u00fcncelleme ba\u015far\u0131l\u0131.\");\n    }\n\n    public override void UrunCikar(string userId, string productId)\n    {\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} \u00fcr\u00fcn\u00fc {productId} sepetten \u00e7\u0131kard\u0131.\");\n        _sepetServisi.UrunCikar(userId, productId);\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} i\u00e7in sepet g\u00fcncelleme ba\u015far\u0131l\u0131.\");\n    }\n\n    public override void MiktarGuncelle(string userId, string productId, int newQuantity)\n    {\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} \u00fcr\u00fcn\u00fc {productId} miktar\u0131n\u0131 {newQuantity} olarak g\u00fcncelledi.\");\n        _sepetServisi.MiktarGuncelle(userId, productId, newQuantity);\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} i\u00e7in sepet g\u00fcncelleme ba\u015far\u0131l\u0131.\");\n    }\n\n    public override void SepetiBosalt(string userId)\n    {\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} sepetini bo\u015faltt\u0131.\");\n        _sepetServisi.SepetiBosalt(userId);\n        _logger.LogInfo($\"[LOG] Kullan\u0131c\u0131 {userId} i\u00e7in sepet bo\u015faltma ba\u015far\u0131l\u0131.\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Ve son olarak, ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu (Dependency Injection - DI) veya manuel olarak bu dekorat\u00f6r\u00fc nas\u0131l kullanaca\u011f\u0131m\u0131z:<\/p>\n<pre><code>\n\/\/ Uygulama ba\u015flang\u0131c\u0131 veya ba\u011f\u0131ml\u0131l\u0131k yap\u0131land\u0131rmas\u0131\npublic class ECommerceApp\n{\n    public static void Main(string[] args)\n    {\n        \/\/ Mock logger ve repository (ger\u00e7ek uygulamada DI ile inject edilir)\n        ILogger logger = new ConsoleLogger(); \/\/ Basit bir konsol logger\n        ISepetRepository sepetRepository = new InMemorySepetRepository(); \/\/ Basit bir bellek i\u00e7i repo\n\n        \/\/ Temel sepet servisi\n        ISepetServisi gercekSepetServisi = new SomutSepetServisi(sepetRepository);\n\n        \/\/ Kay\u0131t \u00f6zellikli sepet servisi\n        ISepetServisi loglananSepetServisi = new LoglamaSepetServisiDekoratoru(gercekSepetServisi, logger);\n\n        Console.WriteLine(\"--- Loglu Sepet \u0130\u015flemleri ---\");\n        loglananSepetServisi.UrunEkle(\"user123\", \"P001\", 2);\n        loglananSepetServisi.MiktarGuncelle(\"user123\", \"P001\", 3);\n        loglananSepetServisi.UrunCikar(\"user123\", \"P002\");\n        loglananSepetServisi.SepetiBosalt(\"user123\");\n        Console.WriteLine(\"-----------------------------\");\n\n        \/\/ \u0130htiya\u00e7 olursa logsuz servis de kullan\u0131labilir\n        Console.WriteLine(\"\\n--- Logsuz Sepet \u0130\u015flemleri (Test Ama\u00e7l\u0131) ---\");\n        gercekSepetServisi.UrunEkle(\"user456\", \"P005\", 1);\n        Console.WriteLine(\"------------------------------------------\");\n    }\n}\n\n\/\/ Basit ILogger ve ISepetRepository implementasyonlar\u0131\npublic interface ILogger { void LogInfo(string message); }\npublic class ConsoleLogger : ILogger { public void LogInfo(string message) { Console.WriteLine(message); } }\npublic interface ISepetRepository\n{\n    void AddProductToCart(string userId, string productId, int quantity);\n    void RemoveProductFromCart(string userId, string productId);\n    void UpdateProductQuantity(string userId, string productId, int newQuantity);\n    void ClearCart(string userId);\n}\npublic class InMemorySepetRepository : ISepetRepository\n{\n    public void AddProductToCart(string userId, string productId, int quantity) { \/* ... *\/ }\n    public void RemoveProductFromCart(string userId, string productId) { \/* ... *\/ }\n    public void UpdateProductQuantity(string userId, string productId, int newQuantity) { \/* ... *\/ }\n    public void ClearCart(string userId) { \/* ... *\/ }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu yeni yap\u0131 ile birlikte, aktivite kay\u0131tlar\u0131 tamamen <code>LoglamaSepetServisiDekoratoru<\/code> i\u00e7ine ta\u015f\u0131nm\u0131\u015ft\u0131r. <code>SomutSepetServisi<\/code> art\u0131k sadece sepetin i\u015f mant\u0131\u011f\u0131na odaklan\u0131r. Bu, kod tekrar\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r, bak\u0131m\u0131 kolayla\u015ft\u0131r\u0131r ve her bir mod\u00fcl\u00fcn tek bir sorumlulu\u011fu olmas\u0131na yard\u0131mc\u0131 olur (SRP - Single Responsibility Principle). Ayr\u0131ca, bir g\u00fcn kay\u0131t tutma \u015feklinizi de\u011fi\u015ftirmek istedi\u011finizde, sadece dekorat\u00f6r s\u0131n\u0131f\u0131n\u0131 g\u00fcncellemeniz veya yeni bir dekorat\u00f6r eklemeniz yeterli olacakt\u0131r. Tahmini olarak, bu yakla\u015f\u0131m aktivite kayd\u0131yla ilgili kod sat\u0131r\u0131 miktar\u0131n\u0131 ve bak\u0131m karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 %70 veya daha fazla azaltabilir.<\/p>\n<div class=\"tip-box\">\n  Mobil Uyumluluk Notu: HTML yap\u0131s\u0131n\u0131 mobil cihazlarda iyi g\u00f6r\u00fcnmesi i\u00e7in esnek kutular (flexbox) veya grid sistemleri ile tasarlayabilirsiniz. CSS media query'ler ile farkl\u0131 ekran boyutlar\u0131na \u00f6zel stiller tan\u0131mlayarak i\u00e7eri\u011fin d\u00fczenini optimize edebilirsiniz. \u00d6rne\u011fin, k\u00fc\u00e7\u00fck ekranlarda kolonlar\u0131 alt alta s\u0131ralayarak okunabilirli\u011fi art\u0131rabilirsiniz.\n<\/div>\n<h2>Performans ve Geni\u015fletilebilirlik: Decorator Pattern'\u0131n Gizli G\u00fc\u00e7leri Nelerdir?<\/h2>\n<p>Decorator Pattern, sadece kod tekrar\u0131n\u0131 azaltmakla kalmaz, ayn\u0131 zamanda bir uygulaman\u0131n performans\u0131n\u0131 ve geni\u015fletilebilirli\u011fini de \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir. Ancak, her tasar\u0131m deseni gibi, do\u011fru ba\u011flamda ve bilin\u00e7li bir \u015fekilde kullan\u0131lmas\u0131 gerekir. Gelin, bu desenin \"gizli g\u00fc\u00e7lerine\" ve olas\u0131 performans etkilerine daha yak\u0131ndan bakal\u0131m.<\/p>\n<h3>Dekorat\u00f6rleri Zincirleme ve Dinamik Davran\u0131\u015f<\/h3>\n<p>Decorator Pattern'\u0131n en g\u00fc\u00e7l\u00fc yanlar\u0131ndan biri, birden fazla dekorat\u00f6r\u00fc birbiri \u00fczerine zincirleyebilme yetene\u011fidir. Bu, ayn\u0131 temel nesneye farkl\u0131 sorumluluklar\u0131 dinamik olarak ekleyebilece\u011finiz anlam\u0131na gelir. \u00d6rne\u011fin, bir sepet servisi i\u00e7in hem kay\u0131t tutma, hem yetkilendirme kontrol\u00fc, hem de \u00f6nbellekleme (caching) \u00f6zelliklerini eklemek isteyebilirsiniz. Bunu her bir \u00f6zelli\u011fi ayr\u0131 bir dekorat\u00f6r olarak uygulayarak ve bu dekorat\u00f6rleri birbiri \u00fczerine sarmalayarak kolayca ba\u015farabilirsiniz:<\/p>\n<pre><code>\n\/\/ Farkl\u0131 dekorat\u00f6rler\nISepetServisi sepetServisi = new SomutSepetServisi(sepetRepository);\nISepetServisi yetkiKontrolluServis = new YetkilendirmeSepetServisiDekoratoru(sepetServisi, yetkiKontrolcusu);\nISepetServisi loglananYetkiliServis = new LoglamaSepetServisiDekoratoru(yetkiKontrolluServis, logger);\nISepetServisi onbellekliLoglananYetkiliServis = new OnbelleklemeSepetServisiDekoratoru(loglananYetkiliServis, cacheServisi);\n\n\/\/ Art\u0131k 'onbellekliLoglananYetkiliServis' hem \u00f6nbellekleme, hem loglama, hem yetkilendirme \u00f6zelliklerine sahip!\nonbellekliLoglananYetkiliServis.UrunEkle(\"user789\", \"P010\", 1);\n<\/pre>\n<p><\/code><\/p>\n<p>Bu zincirleme yap\u0131s\u0131, kod taban\u0131n\u0131zda her bir \u00f6zellik kombinasyonu i\u00e7in ayr\u0131 bir s\u0131n\u0131f olu\u015fturmaktan sizi kurtar\u0131r. Her \u00f6zellik, kendi dekorat\u00f6r\u00fc i\u00e7inde kaps\u00fcllenir ve istedi\u011finiz zaman eklenip \u00e7\u0131kar\u0131labilir. Bu, uygulaman\u0131za inan\u0131lmaz bir esneklik ve dinamik davran\u0131\u015f kazand\u0131r\u0131r. Yeni bir \u00f6zellik (\u00f6rne\u011fin, bir bildirim servisi) eklemek istedi\u011finizde, sadece yeni bir dekorat\u00f6r yazar ve onu mevcut zincire eklersiniz; var olan hi\u00e7bir kodu de\u011fi\u015ftirmenize gerek kalmaz.<\/p>\n<h3>Performans \u00dczerindeki Etkileri: Potansiyel Ek Y\u00fckler<\/h3>\n<p>Her soyutlama katman\u0131 gibi, Decorator Pattern da performansa belirli bir ek y\u00fck getirebilir. Her dekorat\u00f6r, temel metod \u00e7a\u011fr\u0131s\u0131n\u0131 sarmalad\u0131\u011f\u0131 ve kendi ek mant\u0131\u011f\u0131n\u0131 uygulad\u0131\u011f\u0131 i\u00e7in, bir metod \u00e7a\u011fr\u0131s\u0131n\u0131n ger\u00e7ekle\u015fmesi i\u00e7in birden fazla nesne \u00fczerinden ge\u00e7mesi gerekebilir. Bu ek y\u00fckler \u015funlar\u0131 i\u00e7erebilir:<\/p>\n<ul>\n<li><strong>Nesne Olu\u015fturma:<\/strong> Her bir dekorat\u00f6r, bellekte ek bir nesne olu\u015fturulmas\u0131 anlam\u0131na gelir. \u00c7ok say\u0131da dekorat\u00f6r\u00fcn zincirlendi\u011fi ve s\u0131k\u00e7a olu\u015fturuldu\u011fu senaryolarda bu, bellek t\u00fcketimini art\u0131rabilir.<\/li>\n<li><strong>Metod \u00c7a\u011fr\u0131s\u0131 Y\u00fck\u00fc:<\/strong> Temel metod \u00e7a\u011fr\u0131s\u0131na ula\u015fmak i\u00e7in birden fazla sanal metod \u00e7a\u011fr\u0131s\u0131 (virtual method call) yap\u0131lmas\u0131 gerekebilir. Modern JIT derleyicileri bu t\u00fcr y\u00fckleri optimize etse de, a\u015f\u0131r\u0131 derin bir dekorat\u00f6r zinciri teorik olarak k\u00fc\u00e7\u00fck bir performans d\u00fc\u015f\u00fc\u015f\u00fcne neden olabilir.<\/li>\n<li><strong>Ek \u0130\u015flem Y\u00fck\u00fc:<\/strong> Her dekorat\u00f6r, ek bir sorumluluk (\u00f6rne\u011fin kay\u0131t tutma, yetkilendirme kontrol\u00fc, \u00f6nbellek kontrol\u00fc) ekledi\u011fi i\u00e7in, bu ek i\u015f mant\u0131\u011f\u0131n\u0131n kendisi de zaman ve kaynak t\u00fcketir. Ancak bu, dekorat\u00f6r deseninden ba\u011f\u0131ms\u0131z olarak, bu \u00f6zelliklerin bir \u015fekilde uygulanmas\u0131 gerekti\u011fi ger\u00e7e\u011fidir.<\/li>\n<\/ul>\n<p>Pratikte, \u00e7o\u011fu modern uygulamada ve donan\u0131mda bu performans ek y\u00fckleri genellikle ihmal edilebilir d\u00fczeydedir ve elde edilen mimari faydalar (bak\u0131m kolayl\u0131\u011f\u0131, esneklik, test edilebilirlik) bu k\u00fc\u00e7\u00fck maliyetten \u00e7ok daha de\u011ferlidir. Performans\u0131n a\u015f\u0131r\u0131 kritik oldu\u011fu y\u00fcksek frekansl\u0131, d\u00fc\u015f\u00fck gecikmeli sistemlerde, her soyutlama katman\u0131 dikkatle de\u011ferlendirilmeli ve gerekirse farkl\u0131 optimizasyon yakla\u015f\u0131mlar\u0131 (\u00f6rne\u011fin AOP k\u00fct\u00fcphaneleri) d\u00fc\u015f\u00fcn\u00fclmelidir. Ancak aktivite kayd\u0131 gibi \u00e7o\u011fu \u00e7apraz kesen endi\u015fe i\u00e7in Decorator Pattern, harika bir dengeli \u00e7\u00f6z\u00fcm sunar.<\/p>\n<h3>Ba\u011f\u0131ml\u0131l\u0131k Enjeksiyonu (DI) ile Entegrasyon<\/h3>\n<p>Decorator Pattern, modern uygulamalarda s\u0131kl\u0131kla kullan\u0131lan Ba\u011f\u0131ml\u0131l\u0131k Enjeksiyonu (Dependency Injection - DI) konteynerleri ile kusursuz bir \u015fekilde entegre olur. DI konteynerleri (\u00f6rne\u011fin .NET'teki <code>Microsoft.Extensions.DependencyInjection<\/code>, Spring'deki IoC konteyneri), dekorat\u00f6r zincirlerini otomatik olarak olu\u015fturmak ve y\u00f6netmek i\u00e7in kullan\u0131labilir. Bu, istemci kodunun hangi dekorat\u00f6rlerin uygulanaca\u011f\u0131 veya hangi s\u0131rayla sarmalanaca\u011f\u0131 hakk\u0131nda bilgi sahibi olmas\u0131na gerek kalmadan temiz ve esnek bir mimari olu\u015fturman\u0131z\u0131 sa\u011flar.<\/p>\n<pre><code>\n\/\/ C# .NET Core IServiceCollection ile yap\u0131land\u0131rma \u00f6rne\u011fi\npublic void ConfigureServices(IServiceCollection services)\n{\n    \/\/ Temel servisi kaydet\n    services.AddScoped<ISepetServisi, SomutSepetServisi>();\n\n    \/\/ Dekorasyonlar\u0131 zincirle (kay\u0131t -> yetkilendirme -> \u00f6nbellekleme)\n    services.Decorate<ISepetServisi, LoglamaSepetServisiDekoratoru>();\n    services.Decorate<ISepetServisi, YetkilendirmeSepetServisiDekoratoru>();\n    services.Decorate<ISepetServisi, OnbelleklemeSepetServisiDekoratoru>();\n\n    \/\/ Di\u011fer ba\u011f\u0131ml\u0131l\u0131klar\n    services.AddSingleton<ILogger, ConsoleLogger>();\n    services.AddScoped<ISepetRepository, InMemorySepetRepository>();\n    services.AddScoped<IYetkiKontrolcusu, DummyYetkiKontrolcusu>();\n    services.AddSingleton<ICacheServisi, InMemoryCacheServisi>();\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu yap\u0131land\u0131rma ile, uygulaman\u0131n herhangi bir yerinde <code>ISepetServisi<\/code> talep edildi\u011finde, DI konteyneri otomatik olarak en d\u0131\u015ftaki dekorat\u00f6rden ba\u015flayarak (bu \u00f6rnekte <code>OnbelleklemeSepetServisiDekoratoru<\/code>) t\u00fcm zinciri olu\u015fturacak ve istemciye tamamen dekore edilmi\u015f servisi sa\u011flayacakt\u0131r. Bu, uygulaman\u0131n mod\u00fclerli\u011fini ve bak\u0131labilirli\u011fini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Geli\u015ftiricilerin, i\u015f mant\u0131\u011f\u0131n\u0131 de\u011fi\u015ftirmeden veya mevcut kodda karma\u015f\u0131k ba\u011f\u0131ml\u0131l\u0131k yap\u0131land\u0131rmalar\u0131 yapmadan yeni \u00f6zellikler eklemesine olanak tan\u0131r. K\u0131sacas\u0131, Decorator Pattern'\u0131n geni\u015fletilebilirlik g\u00fcc\u00fc, DI ile birle\u015fti\u011finde zirveye ula\u015f\u0131r.<\/p>\n<h2>Decorator Pattern Ne Zaman Kullan\u0131lmal\u0131, Ne Zaman Ka\u00e7\u0131n\u0131lmal\u0131?<\/h2>\n<p>Decorator Pattern, aktivite kay\u0131tlar\u0131 gibi \u00e7apraz kesen endi\u015felerin y\u00f6netiminde harika bir ara\u00e7 olsa da, her probleme uygun de\u011fildir. Do\u011fru ba\u011flamda kullan\u0131ld\u0131\u011f\u0131nda parlarken, yanl\u0131\u015f yerde kullan\u0131ld\u0131\u011f\u0131nda kodu gereksiz yere karma\u015f\u0131kla\u015ft\u0131rabilir. Bu nedenle, ne zaman kullan\u0131laca\u011f\u0131n\u0131 ve ne zaman alternatiflere y\u00f6nelmek gerekti\u011fini iyi anlamak \u00f6nemlidir.<\/p>\n<h3>Decorator Pattern Ne Zaman Parlar?<\/h3>\n<ol>\n<li><strong>Sorumluluklar\u0131 Dinamik Olarak Ekleme \u0130htiyac\u0131:<\/strong> Bir nesneye \u00e7al\u0131\u015fma zaman\u0131nda yeni i\u015flevsellik eklemek istedi\u011finizde idealdir. \u00d6rne\u011fin, belirli ko\u015fullara g\u00f6re (\u00f6rne\u011fin, kullan\u0131c\u0131n\u0131n rol\u00fc, sistemin modu) farkl\u0131 davran\u0131\u015flar sergilemesi gereken bir servisiniz varsa.<\/li>\n<li><strong>\u00c7apraz Kesen Endi\u015felerin Y\u00f6netimi:<\/strong> Kay\u0131t (logging), yetkilendirme (authorization), \u00f6nbellekleme (caching), performans \u00f6l\u00e7\u00fcm\u00fc (monitoring), hata i\u015fleme (error handling) gibi birden fazla mod\u00fcl\u00fc etkileyen ancak birincil i\u015f mant\u0131\u011f\u0131na ait olmayan i\u015flevler i\u00e7in m\u00fckemmeldir. Decorator, bu endi\u015feleri i\u015f mant\u0131\u011f\u0131ndan ay\u0131rarak Single Responsibility Principle'\u0131 (Tek Sorumluluk Prensibi) destekler.<\/li>\n<li><strong>Kal\u0131t\u0131m Hiyerar\u015fisi Patlamas\u0131n\u0131 \u00d6nleme:<\/strong> E\u011fer kal\u0131t\u0131m yoluyla i\u015flevsellik eklemeye \u00e7al\u0131\u015f\u0131rken \u00e7ok say\u0131da alt s\u0131n\u0131f olu\u015fturmak zorunda kal\u0131yorsan\u0131z (\u00f6rne\u011fin, <code>SutluKremaliKahve<\/code>, <code>SutluSekerliKahve<\/code> gibi), Decorator Pattern bu \"s\u0131n\u0131f hiyerar\u015fisi patlamas\u0131n\u0131\" \u00f6nleyerek daha esnek bir alternatif sunar. Her \u00f6zellik i\u00e7in ayr\u0131 bir s\u0131n\u0131f olu\u015fturmak yerine, bunlar\u0131 dekorat\u00f6rler arac\u0131l\u0131\u011f\u0131yla zincirleyebilirsiniz.<\/li>\n<li><strong>Mevcut Kodun De\u011fi\u015ftirilmeden Geni\u015fletilmesi (Open\/Closed Principle):<\/strong> Bir s\u0131n\u0131f\u0131n veya aray\u00fcz\u00fcn davran\u0131\u015f\u0131n\u0131, orijinal kodu de\u011fi\u015ftirmeden geni\u015fletmek istedi\u011finizde \u00e7ok etkilidir. Bu, uygulaman\u0131z\u0131n daha az hata bar\u0131nd\u0131rmas\u0131n\u0131 ve gelecekteki de\u011fi\u015fikliklere daha a\u00e7\u0131k olmas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ol>\n<h3>Decorator Pattern Ne Zaman Ka\u00e7\u0131n\u0131lmal\u0131 veya Alternatifler D\u00fc\u015f\u00fcn\u00fclmeli?<\/h3>\n<ol>\n<li><strong>\u00c7ok Fazla K\u00fc\u00e7\u00fck Nesne Yarat\u0131lmas\u0131:<\/strong> E\u011fer dekorat\u00f6r zinciriniz \u00e7ok uzun ve her dekorat\u00f6r \u00e7ok basit bir i\u015f yap\u0131yorsa, bu durum gereksiz yere fazla nesne olu\u015fturulmas\u0131na ve kodun okunurlu\u011funun azalmas\u0131na neden olabilir. Bu t\u00fcr durumlarda, daha kapsaml\u0131 bir dekorat\u00f6r veya ba\u015fka bir desen daha uygun olabilir.<\/li>\n<li><strong>Karma\u015f\u0131kl\u0131\u011f\u0131n Gereksiz Artmas\u0131:<\/strong> Basit bir sorunu \u00e7\u00f6zmek i\u00e7in Decorator Pattern'\u0131 kullanmak, gereksiz soyutlamalar ve aray\u00fczler yaratarak kodu karma\u015f\u0131kla\u015ft\u0131rabilir. E\u011fer bir nesnenin davran\u0131\u015f\u0131n\u0131 nadiren veya yaln\u0131zca birka\u00e7 sabit yolla geni\u015fletmeniz gerekiyorsa, basit kal\u0131t\u0131m veya kompozisyon yeterli olabilir.<\/li>\n<li><strong>AOP (Aspect-Oriented Programming) Alternatifi:<\/strong> Kay\u0131t, yetkilendirme gibi \u00e7apraz kesen endi\u015feler i\u00e7in AOP k\u00fct\u00fcphaneleri (\u00f6rne\u011fin AspectJ, PostSharp) de g\u00fc\u00e7l\u00fc bir alternatiftir. AOP, bu t\u00fcr endi\u015feleri \"enjeksiyon\" veya \"vekil (proxy) olu\u015fturma\" yoluyla otomatik olarak ana i\u015f mant\u0131\u011f\u0131na ekleyerek kod tekrar\u0131n\u0131 azalt\u0131r. Decorator Pattern'a benzer bir amaca hizmet etse de, farkl\u0131 bir uygulama mekanizmas\u0131na sahiptir ve baz\u0131 durumlarda daha az manuel yap\u0131land\u0131rma gerektirebilir.<\/li>\n<li><strong>Performans\u0131n A\u015f\u0131r\u0131 Kritik Oldu\u011fu Durumlar:<\/strong> \u00c7ok y\u00fcksek performans gerektiren, mikrosaniyelerle \u00f6l\u00e7\u00fclen gecikmelerin bile \u00f6nemli oldu\u011fu sistemlerde, her soyutlama katman\u0131 (ve dolay\u0131s\u0131yla her sanal metod \u00e7a\u011fr\u0131s\u0131) dikkatle de\u011ferlendirilmelidir. Bu t\u00fcr durumlarda, daha d\u00fc\u015f\u00fck seviyeli, daha az soyutlama i\u00e7eren optimizasyonlar veya AOP gibi derleme zaman\u0131 m\u00fcdahaleleri daha uygun olabilir.<\/li>\n<li><strong>Nesnenin Kimli\u011finin \u00d6nemli Oldu\u011fu Durumlar:<\/strong> Decorator Pattern, bir nesnenin kimli\u011fini de\u011fi\u015ftirmeden davran\u0131\u015f\u0131n\u0131 geni\u015fletir. Ancak, e\u011fer dekorasyon i\u015flemi nesnenin \"kimli\u011fini\" (\u00f6rne\u011fin, <code>==<\/code> operat\u00f6r\u00fc veya hash kodu) de\u011fi\u015ftirmemesi gereken ancak istemci kodunun bu kimli\u011fi kontrol etti\u011fi durumlarda dikkatli olunmal\u0131d\u0131r. Genellikle, dekore edilmi\u015f nesne, temel nesnenin bir referans\u0131n\u0131 tuttu\u011fu i\u00e7in kimlik koruma sa\u011flan\u0131r, ancak bu bir tasar\u0131m detay\u0131d\u0131r.<\/li>\n<\/ol>\n<p>\u00d6zetle, Decorator Pattern g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r ancak her zaman en iyi \u00e7\u00f6z\u00fcm de\u011fildir. Uygulaman\u0131z\u0131n ihtiya\u00e7lar\u0131n\u0131, karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 ve gelecekteki geni\u015fletilebilirlik beklentilerini dikkatlice de\u011ferlendirerek do\u011fru karar\u0131 vermelisiniz. Aktivite kayd\u0131 gibi tekrarlayan ve \u00e7apraz kesen g\u00f6revler i\u00e7in genellikle m\u00fckemmel bir se\u00e7imdir, \u00e7\u00fcnk\u00fc i\u015f mant\u0131\u011f\u0131n\u0131 temiz tutarken bu t\u00fcr g\u00f6revleri zarif\u00e7e ele alman\u0131z\u0131 sa\u011flar.<\/p>\n<h2>Sonu\u00e7: Tekrarlayan Koddan Temiz Mimariye Ge\u00e7i\u015fin Anahtar\u0131<\/h2>\n<p>Modern yaz\u0131l\u0131m geli\u015ftirme, s\u00fcrekli de\u011fi\u015fen gereksinimler ve artan karma\u015f\u0131kl\u0131kla karakterize edilir. Bu ortamda, kod tekrar\u0131 ve bak\u0131m\u0131 zor yap\u0131lar, geli\u015ftirme s\u00fcrecini yava\u015flatan ve hatalara davetiye \u00e7\u0131karan en b\u00fcy\u00fck engellerden biridir. Aktivite kayd\u0131 gibi uygulaman\u0131n bir\u00e7ok farkl\u0131 noktas\u0131nda ortaya \u00e7\u0131kan \u00e7apraz kesen endi\u015feler, bu tekrar\u0131n ve karma\u015f\u0131kl\u0131\u011f\u0131n en s\u0131k rastlanan kaynaklar\u0131ndan biridir.<\/p>\n<p>Bu makalede inceledi\u011fimiz Decorator Pattern, tam da bu t\u00fcr sorunlara zarif ve etkili bir \u00e7\u00f6z\u00fcm sunar. \u0130\u015f mant\u0131\u011f\u0131n\u0131 kay\u0131t tutma veya di\u011fer ek sorumluluklardan ay\u0131rarak, uygulamalar\u0131m\u0131z\u0131n \u00e7ekirdek i\u015flevselli\u011fini saf, okunabilir ve test edilebilir tutmam\u0131z\u0131 sa\u011flar. Bu sayede, aktivite kayd\u0131 gibi tekrarlayan g\u00f6revler, ana i\u015f mant\u0131\u011f\u0131n\u0131n i\u00e7ine da\u011f\u0131lmaktan kurtulur ve merkezi, de\u011fi\u015ftirilmesi kolay bir yap\u0131ya kavu\u015fur.<\/p>\n<p>Decorator Pattern'\u0131n temel felsefesi, bir nesneye mevcut yap\u0131s\u0131n\u0131 de\u011fi\u015ftirmeden dinamik olarak yeni sorumluluklar eklemektir. Bu, A\u00e7\u0131k\/Kapal\u0131 Prensibi'ne (Open\/Closed Principle) m\u00fckemmel bir \u015fekilde uyar; yani, bir mod\u00fcl geni\u015fletmeye a\u00e7\u0131k olmal\u0131 ancak de\u011fi\u015fiklik yapmaya kapal\u0131 olmal\u0131d\u0131r. Aktivite kay\u0131tlar\u0131 \u00f6rne\u011fimizde g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi, bir kez temel servisimizi olu\u015fturduktan sonra, kay\u0131t \u00f6zelli\u011fini eklemek i\u00e7in mevcut kodu de\u011fi\u015ftirmemize gerek kalmad\u0131, sadece yeni bir dekorat\u00f6r sarmalad\u0131k. Bu yakla\u015f\u0131m, sadece aktivite kayd\u0131nda de\u011fil, yetkilendirme, \u00f6nbellekleme, performans izleme gibi bir\u00e7ok alanda da uygulanabilir ve yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecini %70 veya daha fazla oranda basitle\u015ftirebilir.<\/p>\n<p>Bu desenin sundu\u011fu esneklik, ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu konteynerleriyle birle\u015fti\u011finde daha da g\u00fc\u00e7lenir. Uygulaman\u0131n farkl\u0131 katmanlar\u0131 aras\u0131nda sa\u011flam ve s\u00fcrd\u00fcr\u00fclebilir bir ileti\u015fim kurarak, temiz mimari prensiplerine ula\u015fman\u0131n anahtarlar\u0131ndan biri haline gelir. Unutmay\u0131n, iyi bir mimari, de\u011fi\u015fime h\u0131zl\u0131 ve g\u00fcvenli bir \u015fekilde adapte olabilen bir mimaridir. Decorator Pattern, bu adaptasyonu sa\u011flamak i\u00e7in bize g\u00fc\u00e7l\u00fc bir ara\u00e7 sunar.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ol>\n<li>\n        <strong>Decorator Pattern ile AOP (Aspect-Oriented Programming) aras\u0131ndaki temel fark nedir?<\/strong><\/p>\n<p>Decorator Pattern ve AOP, \u00e7apraz kesen endi\u015feleri (logging, caching vb.) ana i\u015f mant\u0131\u011f\u0131ndan ay\u0131rma konusunda benzer hedeflere sahiptir. Ancak uygulama bi\u00e7imleri farkl\u0131d\u0131r. Decorator, \u00e7al\u0131\u015fma zaman\u0131nda nesneleri sarmalayarak (kompozisyon) ek davran\u0131\u015flar ekler ve kod seviyesinde soyutlamalarla \u00e7al\u0131\u015f\u0131r. AOP ise genellikle derleme zaman\u0131 veya \u00e7al\u0131\u015fma zaman\u0131 vekil (proxy) olu\u015fturma teknikleri kullanarak, kodun belirli \"birle\u015fme noktalar\u0131na\" (join points) otomatik olarak ek davran\u0131\u015flar\u0131 \"serpi\u015ftirir\" (weaving). AOP daha geni\u015f bir kapsama sahip olabilir ve genellikle daha az manuel yap\u0131land\u0131rma gerektirir, ancak \u00f6\u011frenme e\u011frisi daha dik olabilir. Decorator, daha basit ve do\u011frudan bir yakla\u015f\u0131md\u0131r.<\/p>\n<\/li>\n<li>\n        <strong>Decorator Pattern kullanmak performans\u0131 olumsuz etkiler mi?<\/strong><\/p>\n<p>Her soyutlama katman\u0131 gibi Decorator Pattern da teorik olarak k\u00fc\u00e7\u00fck bir performans ek y\u00fck\u00fc getirebilir (ek nesne olu\u015fturma, sanal metod \u00e7a\u011fr\u0131lar\u0131). Ancak \u00e7o\u011fu modern uygulamada ve donan\u0131mda bu ek y\u00fckler genellikle ihmal edilebilir d\u00fczeydedir ve elde edilen mimari faydalar (kod tekrar\u0131n\u0131 azaltma, bak\u0131m kolayl\u0131\u011f\u0131, esneklik, test edilebilirlik) bu maliyetten \u00e7ok daha de\u011ferlidir. Performans\u0131n a\u015f\u0131r\u0131 kritik oldu\u011fu senaryolarda dikkatli bir analiz ve gerekirse alternatif yakla\u015f\u0131mlar d\u00fc\u015f\u00fcn\u00fclmelidir.<\/p>\n<\/li>\n<li>\n        <strong>Hangi durumlarda Decorator yerine miras (inheritance) kullanmal\u0131y\u0131m?<\/strong><\/p>\n<p>E\u011fer bir s\u0131n\u0131f\u0131n davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmek veya geni\u015fletmek istedi\u011finizde, sadece birka\u00e7 sabit varyasyonunuz varsa ve bu varyasyonlar\u0131n say\u0131s\u0131 gelecekte pek de\u011fi\u015fmeyecekse, basit kal\u0131t\u0131m yeterli olabilir. Decorator Pattern, \u00f6zellikle \u00e7ok say\u0131da farkl\u0131 kombinasyonun dinamik olarak olu\u015fturulmas\u0131 gerekti\u011fi veya mevcut kodu de\u011fi\u015ftirmeden yeni \u00f6zelliklerin eklenmesi gerekti\u011fi durumlarda parlar. Kal\u0131t\u0131m genellikle \"bir \u015feydir\" (is-a) ili\u015fkisini ifade ederken, Decorator \"bir \u015feyi sarar\" (wraps-a) ili\u015fkisini ifade eder ve daha fazla esneklik sunar.<\/p>\n<\/li>\n<li>\n        <strong>Decorator Pattern'\u0131n alternatifi olarak ba\u015fka hangi tasar\u0131m desenleri d\u00fc\u015f\u00fcn\u00fclebilir?<\/strong><\/p>\n<p>\u00c7apraz kesen endi\u015felerin y\u00f6netiminde Decorator Pattern'a alternatif olarak Chain of Responsibility, Proxy Pattern veya Facade Pattern gibi di\u011fer yap\u0131sal desenler belirli senaryolarda kullan\u0131labilir. Ancak aktivite kayd\u0131 gibi birincil i\u015f mant\u0131\u011f\u0131n\u0131 de\u011fi\u015ftirmeden ek \u00f6zellikler ekleme konusunda Decorator olduk\u00e7a \u00f6zelle\u015fmi\u015f ve etkilidir. Ayr\u0131ca daha \u00f6nce bahsedildi\u011fi gibi, Aspect-Oriented Programming (AOP) de g\u00fc\u00e7l\u00fc bir alternatiftir.<\/p>\n<\/li>\n<li>\n        <strong>Decorator Pattern, temiz mimari prensipleriyle nas\u0131l uyum sa\u011flar?<\/strong><\/p>\n<p>Decorator Pattern, \u00f6zellikle SOLID prensiplerinden Tek Sorumluluk Prensibi (Single Responsibility Principle - SRP) ve A\u00e7\u0131k\/Kapal\u0131 Prensibi (Open\/Closed Principle - OCP) ile m\u00fckemmel uyum sa\u011flar. SRP'yi destekleyerek, her s\u0131n\u0131f\u0131n tek bir sorumlulu\u011fu olmas\u0131n\u0131 sa\u011flar (\u00f6rne\u011fin, <code>SomutSiparisServisi<\/code> sadece sipari\u015f i\u015fini yapar, kay\u0131t i\u015fini de\u011fil). OCP'yi destekleyerek de, mevcut kodu de\u011fi\u015ftirmeden yeni i\u015flevsellik eklememize olanak tan\u0131r. Bu da daha mod\u00fcler, esnek ve bak\u0131m\u0131 kolay bir temiz mimari olu\u015fturulmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<\/li>\n<\/ol>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem,&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-33819","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 Daha Basit<\/title>\n<meta name=\"description\" content=\"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-p-daha-basit\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit\" \/>\n<meta property=\"og:description\" content=\"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-p-daha-basit\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-07T11:01:19+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"30 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit\",\"datePublished\":\"2025-11-07T11:01:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/\"},\"wordCount\":4584,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/\",\"name\":\"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 Daha Basit\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-07T11:01:19+00:00\",\"description\":\"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 Daha Basit","description":"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.","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:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-p-daha-basit\/","og_locale":"tr_TR","og_type":"article","og_title":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit","og_description":"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.","og_url":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-p-daha-basit\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-07T11:01:19+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"30 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit","datePublished":"2025-11-07T11:01:19+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/"},"wordCount":4584,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/","url":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/","name":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 Daha Basit","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-07T11:01:19+00:00","description":"Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, uygulaman\u0131n kritik noktalar\u0131ndaki kullan\u0131c\u0131 veya sistem aktivitelerini kaydetmek vazge\u00e7ilmez bir gerekliliktir. Ancak bu i\u015flem, s\u0131kl\u0131kla tekrarlayan kodlara, bak\u0131m\u0131 zorla\u015fan mod\u00fcllere ve mimari karma\u015f\u0131kl\u0131\u011fa yol a\u00e7abilir. Peki, bu kaostan kurtulup aktivite kayd\u0131n\u0131 zarif ve s\u00fcrd\u00fcr\u00fclebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Cevap: Decorator Pattern.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/tekrarlayan-koddan-temiz-mimariye-decorator-pattern-ile-aktivite-kaydi-%70-daha-basit\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Tekrarlayan Koddan Temiz Mimariye: Decorator Pattern ile Aktivite Kayd\u0131 %70 Daha Basit"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33819","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=33819"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33819\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=33819"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=33819"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=33819"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}