[{"data":1,"prerenderedAt":1409},["ShallowReactive",2],{"post-\u002Ftr\u002Fbridge-tasarim-deseni-nedir":3},{"page":4,"translation":1257,"nav":1272,"related":1390,"random":1400},{"id":5,"title":6,"body":7,"categories":1255,"category":1257,"date":1258,"description":1259,"draft":1260,"extension":1261,"image":1262,"kind":1257,"lang":1263,"meta":1264,"navigation":208,"path":1174,"readingTime":229,"seo":1265,"slug":1266,"stem":1267,"tags":1268,"translationKey":1257,"type":1256,"updated":1257,"__hash__":1271},"postsTr\u002Ftr\u002Fbridge-tasarim-deseni-nedir.md","Bridge Tasarım Deseni Nedir?",{"type":8,"value":9,"toc":1246},"minimark",[10,20,33,36,41,48,52,55,79,86,89,92,96,99,102,107,110,113,117,122,125,128,133,136,141,144,148,180,184,187,751,754,1131,1135,1140,1161,1166,1195,1200,1242],[11,12,13,14,19],"p",{},"Bu yazı ",[15,16,18],"a",{"href":17},"\u002Ftr\u002Fdesign-patterns-tasarim-desenleri-nedir","Design Patterns\u002FTasarım Desenleri nedir?"," başlıklı yazı dizisinin bir parçasıdır.",[11,21,22,23,32],{},"Bu içerik ağırlıklı olarak ",[15,24,31],{"href":25,"rel":26,"target":30},"https:\u002F\u002Frefactoring.guru\u002Fdesign-patterns",[27,28,29],"nofollow","noopener","noreferrer","_blank","refactoring.guru"," sitesindeki içeriğin tercümesi ve derlenmesinden oluşturulmuştur.",[11,34,35],{},"Tüm tasarım desenleri ya da diğer adıyla tasarım kalıplarına yönelik ayrıntılı içeriklere yazının sonundaki bağlantılardan ulaşabilirsiniz.",[37,38,40],"h2",{"id":39},"bridge-tasarım-deseninin-amacı","Bridge tasarım deseninin amacı",[11,42,43,47],{},[44,45,46],"strong",{},"Bridge",", Türkçe karşılığı ile köprü büyük sınıfları veya birbiriyle yakın ilişkili sınıfları, birbirinden bağımsız olarak geliştirilebilecek iki ayrı hiyerarşiye bölmenizi sağlayan bir tasarım desenidir.",[37,49,51],{"id":50},"sorun","Sorun",[11,53,54],{},"Abstraction (Soyutlama) ve Implementation (Uygulama) kavramları korkutucu mu geliyor. Paniğe gerek yok, hemen basit iki örnek düşünelim;",[11,56,57,58,62,63,66,67,70,71,74,75,78],{},"Diyelimki ",[59,60,61],"code",{},"Circle"," (Çember) ve ",[59,64,65],{},"Square"," (Kare) gibi bir kaç alt sınıfı olan ",[59,68,69],{},"Shape"," (Şekil) adlı bir sınıfınız olsun. Bu sınıf hiyerarşisini renkleri de dahile decek şekilde genişletmek istiyorsunuz ve bu amaçla ",[59,72,73],{},"Red"," (Kırmızı) ve ",[59,76,77],{},"Blue"," mavi şekil alt sınıflarını oluşturdunuz. Fakat zaten iki şekil alt sınıfınız olduğu için MaviDaire, KırmızıKare gibi dört farklı kombinasyon hazırlamanız gerekecek.",[11,80,81],{},[82,83],"img",{"alt":84,"src":85},"","\u002Fimages\u002Fbridge-tasarim-deseni-nedir\u002Fbridge-tasarim-semasi-sorun.avif",[11,87,88],{},"Sınıf kombinasyonları geometrik olarak artacaktır.",[11,90,91],{},"Yeni şekil tür veya renkleri eklemek hiyerarşinizi eksponensiyel olarak büyütecektir. Örneğin bir üçgen eklemek istediğinizde her iki renk için de ayrı alt sınıflar oluşturmanız gerekecek. Ve daha sonra yeni bir renk eklemek isterseniz her şekil için bir tane olmak üzere üç alt sınıf daha eklemeniz gerekecek. Daha fazlasını ekledikçe bu durum daha da kötüye gidecek.",[37,93,95],{"id":94},"çözüm","Çözüm",[11,97,98],{},"Bu sorunla karşılaşmamızın nedeni şekil alt sınıfını iki bağımsız boyutta genişletmeye çalışmamız. Bu sınıf türetme (class inheritance) yaparken maalesef karşınıza sık çıkacak bir sorundur.",[11,100,101],{},"Köprü deseni (Bridge pattern) bu kalıtsal türetme (inheritance) işini nesne bileşimi haline getirerek çözüyor. Bunun anlamı bu iki boyuttan birini ayrı bir sınıf haline getiriyor ve orijinal sınıf içerisinden buna referans veriyorsunuz, böylece orijinal sınıf diğer sınıfın bütün metod ve durumlarını içermek zorunda kalmıyor.",[11,103,104],{},[82,105],{"alt":84,"src":106},"\u002Fimages\u002Fbridge-tasarim-deseni-nedir\u002Fbridge-tasarim-deseni-cozum.avif",[11,108,109],{},"Sınıf hiyerarşinizin gereksiz büyümesini engellemek için birden fazla ilişkili sınıflara ayırabilirsiniz.",[11,111,112],{},"Bu yaklaşımı uygulayarak renkle ilgili kodları Kırmızı ve Mavi alt sınıfları içine koyabiliriz. Böylece şekil sınıfının sadece ilgili renk sınıfına bir referans tutması yeterli olur.",[37,114,116],{"id":115},"uygulanabilirlik","Uygulanabilirlik",[11,118,119],{},[44,120,121],{},"Belirli bir işlevin çeşitli varyasyonlarını içeren monoloitik bir sınıfı parçalara bölmek ve yönetmek istediğinizde köprü (Bridge) tasarım desenini kulllanın.",[11,123,124],{},"Sınıf büyüdükçe nasıl çalıştığını anlamak daha zor olacak, gerektiğinde değişiklik yapmak daha fazla vakit alacaktır. Varyasyonların birinde yapılan bir değişiklik tüm sınıfta değişiklik yapmayı gerektirebilir. Böyle bir değişiklik genelde hataya açık veya farkedilmeyen kritik yan etkilere neden olabilir.",[11,126,127],{},"Köprü deseni monolotilik bir sınıfı bir kaç sınıf hiyerarşisine döndürmenize olanağ sağlar. Bunu yaptıktan sonra hiyerarşideki sınıfları diğerlerinden bağımsız olarak değiştirebilirsiniz. Bu yaklaşım kodun bakımını kolaylaştırırken mevcut kodda hatalara neden olma riskini de azaltır.",[11,129,130],{},[44,131,132],{},"Bir sınıfı bağımsız birden fazla boyuta genişletecekseniz bu sınıfı kullanın.",[11,134,135],{},"Köprü tüm boyutlar için ayrı sınıflar oluşturmayı önerir. Orijinal sınıf tüm işi kendi yapmaktansa bu alt sınıflara yükler.",[11,137,138],{},[44,139,140],{},"Çalışma anında uygulama yöntemlerini değiştirmek için köprü desenini kullanın.",[11,142,143],{},"Her ne kadar isteğe bağlı da olsa, köprü deseni abstraction (soyutlama) içerisindeki uygulanışı (implementation) değiştirme olanağı sağlar. Basitçe ilgili alana yeni bir değer atayarak bunu sağlayabilirsiniz.",[37,145,147],{"id":146},"diğer-tasarım-desenlerikalıpları-ile-ilişkisi","Diğer tasarım desenleri\u002Fkalıpları ile ilişkisi",[149,150,151,162,171],"ul",{},[152,153,154,157,158,161],"li",{},[44,155,156],{},"Köprü (Bridge)"," uygulamanın farklı bölümlerini birbirinden bağımsız olarak geliştirmeniz için henüz o bölümler kodlanmadan önce geliştirilir. ",[44,159,160],{},"Adaptör"," ise mevcut bir uygulamada kullanılarak birbiri ile uyumsuz sınıfların birlikte çalışmasını sağlar.",[152,163,164,166,167,170],{},[44,165,46],{}," ile birlikte ",[44,168,169],{},"Abstract Factory"," kullanabilirsiniz. Köprünün (bridge) tanımladığı bazı soyutlamalar (abstraction) sadece belirli uygulanışlar (implementation) için geçerli olduğunda bu iş birliği kullanışlıdır. Bu durumda Abstract Factory bu ilişkileri kapsamına alır ve kompleks yapıyı istemci koddan gizlemiş olur.",[152,172,173,176,177,179],{},[44,174,175],{},"Builder"," ve ",[44,178,46],{},"'i birleştirebilirsiniz. Yönetici (director) sınıf soyutlama (abstraction) rolünü oynarken, farklı builder'lar uygulanışı (implementation) belirler.",[37,181,183],{"id":182},"bridge-tasarım-deseni-kod-örnekleri","Bridge Tasarım Deseni Kod Örnekleri",[11,185,186],{},"Örnek PHP Kodu",[188,189,193],"pre",{"className":190,"code":191,"language":192,"meta":84,"style":84},"language-php shiki shiki-themes github-light github-dark","\u003C?php\n\nnamespace RefactoringGuru\\Bridge\\Conceptual;\n\n\u002F**\n * The Abstraction defines the interface for the \"control\" part of the two class\n * hierarchies. It maintains a reference to an object of the Implementation\n * hierarchy and delegates all of the real work to this object.\n *\u002F\nclass Abstraction\n{\n    \u002F**\n     * @var Implementation\n     *\u002F\n    protected $implementation;\n\n    public function __construct(Implementation $implementation)\n    {\n        $this->implementation = $implementation;\n    }\n\n    public function operation(): string\n    {\n        return \"Abstraction: Base operation with:\\n\" .\n            $this->implementation->operationImplementation();\n    }\n}\n\n\u002F**\n * You can extend the Abstraction without changing the Implementation classes.\n *\u002F\nclass ExtendedAbstraction extends Abstraction\n{\n    public function operation(): string\n    {\n        return \"ExtendedAbstraction: Extended operation with:\\n\" .\n            $this->implementation->operationImplementation();\n    }\n}\n\n\u002F**\n * The Implementation defines the interface for all implementation classes. It\n * doesn't have to match the Abstraction's interface. In fact, the two\n * interfaces can be entirely different. Typically the Implementation interface\n * provides only primitive operations, while the Abstraction defines higher-\n * level operations based on those primitives.\n *\u002F\ninterface Implementation\n{\n    public function operationImplementation(): string;\n}\n\n\u002F**\n * Each Concrete Implementation corresponds to a specific platform and\n * implements the Implementation interface using that platform's API.\n *\u002F\nclass ConcreteImplementationA implements Implementation\n{\n    public function operationImplementation(): string\n    {\n        return \"ConcreteImplementationA: Here's the result on the platform A.\\n\";\n    }\n}\n\nclass ConcreteImplementationB implements Implementation\n{\n    public function operationImplementation(): string\n    {\n        return \"ConcreteImplementationB: Here's the result on the platform B.\\n\";\n    }\n}\n\n\u002F**\n * Except for the initialization phase, where an Abstraction object gets linked\n * with a specific Implementation object, the client code should only depend on\n * the Abstraction class. This way the client code can support any abstraction-\n * implementation combination.\n *\u002F\nfunction clientCode(Abstraction $abstraction)\n{\n    \u002F\u002F ...\n\n    echo $abstraction->operation();\n\n    \u002F\u002F ...\n}\n\n\u002F**\n * The client code should be able to work with any pre-configured abstraction-\n * implementation combination.\n *\u002F\n$implementation = new ConcreteImplementationA();\n$abstraction = new Abstraction($implementation);\nclientCode($abstraction);\n\necho \"\\n\";\n\n$implementation = new ConcreteImplementationB();\n$abstraction = new ExtendedAbstraction($implementation);\nclientCode($abstraction);\n","php",[59,194,195,203,210,216,221,227,233,239,245,251,257,263,269,275,281,287,292,298,304,310,316,321,327,332,338,344,349,355,360,365,371,376,382,387,392,397,403,408,413,418,423,428,434,440,446,452,458,463,469,474,480,485,490,495,501,507,512,518,523,529,534,540,545,550,555,561,566,571,576,582,587,592,597,602,608,614,620,626,631,637,642,648,653,659,664,669,674,679,684,690,695,700,706,712,718,723,729,734,740,746],{"__ignoreMap":84},[196,197,200],"span",{"class":198,"line":199},"line",1,[196,201,202],{},"\u003C?php\n",[196,204,206],{"class":198,"line":205},2,[196,207,209],{"emptyLinePlaceholder":208},true,"\n",[196,211,213],{"class":198,"line":212},3,[196,214,215],{},"namespace RefactoringGuru\\Bridge\\Conceptual;\n",[196,217,219],{"class":198,"line":218},4,[196,220,209],{"emptyLinePlaceholder":208},[196,222,224],{"class":198,"line":223},5,[196,225,226],{},"\u002F**\n",[196,228,230],{"class":198,"line":229},6,[196,231,232],{}," * The Abstraction defines the interface for the \"control\" part of the two class\n",[196,234,236],{"class":198,"line":235},7,[196,237,238],{}," * hierarchies. It maintains a reference to an object of the Implementation\n",[196,240,242],{"class":198,"line":241},8,[196,243,244],{}," * hierarchy and delegates all of the real work to this object.\n",[196,246,248],{"class":198,"line":247},9,[196,249,250],{}," *\u002F\n",[196,252,254],{"class":198,"line":253},10,[196,255,256],{},"class Abstraction\n",[196,258,260],{"class":198,"line":259},11,[196,261,262],{},"{\n",[196,264,266],{"class":198,"line":265},12,[196,267,268],{},"    \u002F**\n",[196,270,272],{"class":198,"line":271},13,[196,273,274],{},"     * @var Implementation\n",[196,276,278],{"class":198,"line":277},14,[196,279,280],{},"     *\u002F\n",[196,282,284],{"class":198,"line":283},15,[196,285,286],{},"    protected $implementation;\n",[196,288,290],{"class":198,"line":289},16,[196,291,209],{"emptyLinePlaceholder":208},[196,293,295],{"class":198,"line":294},17,[196,296,297],{},"    public function __construct(Implementation $implementation)\n",[196,299,301],{"class":198,"line":300},18,[196,302,303],{},"    {\n",[196,305,307],{"class":198,"line":306},19,[196,308,309],{},"        $this->implementation = $implementation;\n",[196,311,313],{"class":198,"line":312},20,[196,314,315],{},"    }\n",[196,317,319],{"class":198,"line":318},21,[196,320,209],{"emptyLinePlaceholder":208},[196,322,324],{"class":198,"line":323},22,[196,325,326],{},"    public function operation(): string\n",[196,328,330],{"class":198,"line":329},23,[196,331,303],{},[196,333,335],{"class":198,"line":334},24,[196,336,337],{},"        return \"Abstraction: Base operation with:\\n\" .\n",[196,339,341],{"class":198,"line":340},25,[196,342,343],{},"            $this->implementation->operationImplementation();\n",[196,345,347],{"class":198,"line":346},26,[196,348,315],{},[196,350,352],{"class":198,"line":351},27,[196,353,354],{},"}\n",[196,356,358],{"class":198,"line":357},28,[196,359,209],{"emptyLinePlaceholder":208},[196,361,363],{"class":198,"line":362},29,[196,364,226],{},[196,366,368],{"class":198,"line":367},30,[196,369,370],{}," * You can extend the Abstraction without changing the Implementation classes.\n",[196,372,374],{"class":198,"line":373},31,[196,375,250],{},[196,377,379],{"class":198,"line":378},32,[196,380,381],{},"class ExtendedAbstraction extends Abstraction\n",[196,383,385],{"class":198,"line":384},33,[196,386,262],{},[196,388,390],{"class":198,"line":389},34,[196,391,326],{},[196,393,395],{"class":198,"line":394},35,[196,396,303],{},[196,398,400],{"class":198,"line":399},36,[196,401,402],{},"        return \"ExtendedAbstraction: Extended operation with:\\n\" .\n",[196,404,406],{"class":198,"line":405},37,[196,407,343],{},[196,409,411],{"class":198,"line":410},38,[196,412,315],{},[196,414,416],{"class":198,"line":415},39,[196,417,354],{},[196,419,421],{"class":198,"line":420},40,[196,422,209],{"emptyLinePlaceholder":208},[196,424,426],{"class":198,"line":425},41,[196,427,226],{},[196,429,431],{"class":198,"line":430},42,[196,432,433],{}," * The Implementation defines the interface for all implementation classes. It\n",[196,435,437],{"class":198,"line":436},43,[196,438,439],{}," * doesn't have to match the Abstraction's interface. In fact, the two\n",[196,441,443],{"class":198,"line":442},44,[196,444,445],{}," * interfaces can be entirely different. Typically the Implementation interface\n",[196,447,449],{"class":198,"line":448},45,[196,450,451],{}," * provides only primitive operations, while the Abstraction defines higher-\n",[196,453,455],{"class":198,"line":454},46,[196,456,457],{}," * level operations based on those primitives.\n",[196,459,461],{"class":198,"line":460},47,[196,462,250],{},[196,464,466],{"class":198,"line":465},48,[196,467,468],{},"interface Implementation\n",[196,470,472],{"class":198,"line":471},49,[196,473,262],{},[196,475,477],{"class":198,"line":476},50,[196,478,479],{},"    public function operationImplementation(): string;\n",[196,481,483],{"class":198,"line":482},51,[196,484,354],{},[196,486,488],{"class":198,"line":487},52,[196,489,209],{"emptyLinePlaceholder":208},[196,491,493],{"class":198,"line":492},53,[196,494,226],{},[196,496,498],{"class":198,"line":497},54,[196,499,500],{}," * Each Concrete Implementation corresponds to a specific platform and\n",[196,502,504],{"class":198,"line":503},55,[196,505,506],{}," * implements the Implementation interface using that platform's API.\n",[196,508,510],{"class":198,"line":509},56,[196,511,250],{},[196,513,515],{"class":198,"line":514},57,[196,516,517],{},"class ConcreteImplementationA implements Implementation\n",[196,519,521],{"class":198,"line":520},58,[196,522,262],{},[196,524,526],{"class":198,"line":525},59,[196,527,528],{},"    public function operationImplementation(): string\n",[196,530,532],{"class":198,"line":531},60,[196,533,303],{},[196,535,537],{"class":198,"line":536},61,[196,538,539],{},"        return \"ConcreteImplementationA: Here's the result on the platform A.\\n\";\n",[196,541,543],{"class":198,"line":542},62,[196,544,315],{},[196,546,548],{"class":198,"line":547},63,[196,549,354],{},[196,551,553],{"class":198,"line":552},64,[196,554,209],{"emptyLinePlaceholder":208},[196,556,558],{"class":198,"line":557},65,[196,559,560],{},"class ConcreteImplementationB implements Implementation\n",[196,562,564],{"class":198,"line":563},66,[196,565,262],{},[196,567,569],{"class":198,"line":568},67,[196,570,528],{},[196,572,574],{"class":198,"line":573},68,[196,575,303],{},[196,577,579],{"class":198,"line":578},69,[196,580,581],{},"        return \"ConcreteImplementationB: Here's the result on the platform B.\\n\";\n",[196,583,585],{"class":198,"line":584},70,[196,586,315],{},[196,588,590],{"class":198,"line":589},71,[196,591,354],{},[196,593,595],{"class":198,"line":594},72,[196,596,209],{"emptyLinePlaceholder":208},[196,598,600],{"class":198,"line":599},73,[196,601,226],{},[196,603,605],{"class":198,"line":604},74,[196,606,607],{}," * Except for the initialization phase, where an Abstraction object gets linked\n",[196,609,611],{"class":198,"line":610},75,[196,612,613],{}," * with a specific Implementation object, the client code should only depend on\n",[196,615,617],{"class":198,"line":616},76,[196,618,619],{}," * the Abstraction class. This way the client code can support any abstraction-\n",[196,621,623],{"class":198,"line":622},77,[196,624,625],{}," * implementation combination.\n",[196,627,629],{"class":198,"line":628},78,[196,630,250],{},[196,632,634],{"class":198,"line":633},79,[196,635,636],{},"function clientCode(Abstraction $abstraction)\n",[196,638,640],{"class":198,"line":639},80,[196,641,262],{},[196,643,645],{"class":198,"line":644},81,[196,646,647],{},"    \u002F\u002F ...\n",[196,649,651],{"class":198,"line":650},82,[196,652,209],{"emptyLinePlaceholder":208},[196,654,656],{"class":198,"line":655},83,[196,657,658],{},"    echo $abstraction->operation();\n",[196,660,662],{"class":198,"line":661},84,[196,663,209],{"emptyLinePlaceholder":208},[196,665,667],{"class":198,"line":666},85,[196,668,647],{},[196,670,672],{"class":198,"line":671},86,[196,673,354],{},[196,675,677],{"class":198,"line":676},87,[196,678,209],{"emptyLinePlaceholder":208},[196,680,682],{"class":198,"line":681},88,[196,683,226],{},[196,685,687],{"class":198,"line":686},89,[196,688,689],{}," * The client code should be able to work with any pre-configured abstraction-\n",[196,691,693],{"class":198,"line":692},90,[196,694,625],{},[196,696,698],{"class":198,"line":697},91,[196,699,250],{},[196,701,703],{"class":198,"line":702},92,[196,704,705],{},"$implementation = new ConcreteImplementationA();\n",[196,707,709],{"class":198,"line":708},93,[196,710,711],{},"$abstraction = new Abstraction($implementation);\n",[196,713,715],{"class":198,"line":714},94,[196,716,717],{},"clientCode($abstraction);\n",[196,719,721],{"class":198,"line":720},95,[196,722,209],{"emptyLinePlaceholder":208},[196,724,726],{"class":198,"line":725},96,[196,727,728],{},"echo \"\\n\";\n",[196,730,732],{"class":198,"line":731},97,[196,733,209],{"emptyLinePlaceholder":208},[196,735,737],{"class":198,"line":736},98,[196,738,739],{},"$implementation = new ConcreteImplementationB();\n",[196,741,743],{"class":198,"line":742},99,[196,744,745],{},"$abstraction = new ExtendedAbstraction($implementation);\n",[196,747,749],{"class":198,"line":748},100,[196,750,717],{},[11,752,753],{},"Örnek Python Kodu",[188,755,759],{"className":756,"code":757,"language":758,"meta":84,"style":84},"language-python shiki shiki-themes github-light github-dark","from __future__ import annotations\nfrom abc import ABC, abstractmethod\n\nclass Abstraction:\n    \"\"\"\n    The Abstraction defines the interface for the \"control\" part of the two\n    class hierarchies. It maintains a reference to an object of the\n    Implementation hierarchy and delegates all of the real work to this object.\n    \"\"\"\n\n    def __init__(self, implementation: Implementation) -> None:\n        self.implementation = implementation\n\n    def operation(self) -> str:\n        return (f\"Abstraction: Base operation with:\\n\"\n                f\"{self.implementation.operation_implementation()}\")\n\nclass ExtendedAbstraction(Abstraction):\n    \"\"\"\n    You can extend the Abstraction without changing the Implementation classes.\n    \"\"\"\n\n    def operation(self) -> str:\n        return (f\"ExtendedAbstraction: Extended operation with:\\n\"\n                f\"{self.implementation.operation_implementation()}\")\n\nclass Implementation(ABC):\n    \"\"\"\n    The Implementation defines the interface for all implementation classes. It\n    doesn't have to match the Abstraction's interface. In fact, the two\n    interfaces can be entirely different. Typically the Implementation interface\n    provides only primitive operations, while the Abstraction defines higher-\n    level operations based on those primitives.\n    \"\"\"\n\n    @abstractmethod\n    def operation_implementation(self) -> str:\n        pass\n\n\"\"\"\nEach Concrete Implementation corresponds to a specific platform and implements\nthe Implementation interface using that platform's API.\n\"\"\"\n\nclass ConcreteImplementationA(Implementation):\n    def operation_implementation(self) -> str:\n        return \"ConcreteImplementationA: Here's the result on the platform A.\"\n\nclass ConcreteImplementationB(Implementation):\n    def operation_implementation(self) -> str:\n        return \"ConcreteImplementationB: Here's the result on the platform B.\"\n\ndef client_code(abstraction: Abstraction) -> None:\n    \"\"\"\n    Except for the initialization phase, where an Abstraction object gets linked\n    with a specific Implementation object, the client code should only depend on\n    the Abstraction class. This way the client code can support any abstraction-\n    implementation combination.\n    \"\"\"\n\n    # ...\n\n    print(abstraction.operation(), end=\"\")\n\n    # ...\n\nif __name__ == \"__main__\":\n    \"\"\"\n    The client code should be able to work with any pre-configured abstraction-\n    implementation combination.\n    \"\"\"\n\n    implementation = ConcreteImplementationA()\n    abstraction = Abstraction(implementation)\n    client_code(abstraction)\n\n    print(\"\\n\")\n\n    implementation = ConcreteImplementationB()\n    abstraction = ExtendedAbstraction(implementation)\n    client_code(abstraction)\n","python",[59,760,761,766,771,775,780,785,790,795,800,804,808,813,818,822,827,832,837,841,846,850,855,859,863,867,872,876,880,885,889,894,899,904,909,914,918,922,927,932,937,941,946,951,956,960,964,969,973,978,982,987,991,996,1000,1005,1009,1014,1019,1024,1029,1033,1037,1042,1046,1051,1055,1059,1063,1068,1072,1077,1081,1085,1089,1094,1099,1104,1108,1113,1117,1122,1127],{"__ignoreMap":84},[196,762,763],{"class":198,"line":199},[196,764,765],{},"from __future__ import annotations\n",[196,767,768],{"class":198,"line":205},[196,769,770],{},"from abc import ABC, abstractmethod\n",[196,772,773],{"class":198,"line":212},[196,774,209],{"emptyLinePlaceholder":208},[196,776,777],{"class":198,"line":218},[196,778,779],{},"class Abstraction:\n",[196,781,782],{"class":198,"line":223},[196,783,784],{},"    \"\"\"\n",[196,786,787],{"class":198,"line":229},[196,788,789],{},"    The Abstraction defines the interface for the \"control\" part of the two\n",[196,791,792],{"class":198,"line":235},[196,793,794],{},"    class hierarchies. It maintains a reference to an object of the\n",[196,796,797],{"class":198,"line":241},[196,798,799],{},"    Implementation hierarchy and delegates all of the real work to this object.\n",[196,801,802],{"class":198,"line":247},[196,803,784],{},[196,805,806],{"class":198,"line":253},[196,807,209],{"emptyLinePlaceholder":208},[196,809,810],{"class":198,"line":259},[196,811,812],{},"    def __init__(self, implementation: Implementation) -> None:\n",[196,814,815],{"class":198,"line":265},[196,816,817],{},"        self.implementation = implementation\n",[196,819,820],{"class":198,"line":271},[196,821,209],{"emptyLinePlaceholder":208},[196,823,824],{"class":198,"line":277},[196,825,826],{},"    def operation(self) -> str:\n",[196,828,829],{"class":198,"line":283},[196,830,831],{},"        return (f\"Abstraction: Base operation with:\\n\"\n",[196,833,834],{"class":198,"line":289},[196,835,836],{},"                f\"{self.implementation.operation_implementation()}\")\n",[196,838,839],{"class":198,"line":294},[196,840,209],{"emptyLinePlaceholder":208},[196,842,843],{"class":198,"line":300},[196,844,845],{},"class ExtendedAbstraction(Abstraction):\n",[196,847,848],{"class":198,"line":306},[196,849,784],{},[196,851,852],{"class":198,"line":312},[196,853,854],{},"    You can extend the Abstraction without changing the Implementation classes.\n",[196,856,857],{"class":198,"line":318},[196,858,784],{},[196,860,861],{"class":198,"line":323},[196,862,209],{"emptyLinePlaceholder":208},[196,864,865],{"class":198,"line":329},[196,866,826],{},[196,868,869],{"class":198,"line":334},[196,870,871],{},"        return (f\"ExtendedAbstraction: Extended operation with:\\n\"\n",[196,873,874],{"class":198,"line":340},[196,875,836],{},[196,877,878],{"class":198,"line":346},[196,879,209],{"emptyLinePlaceholder":208},[196,881,882],{"class":198,"line":351},[196,883,884],{},"class Implementation(ABC):\n",[196,886,887],{"class":198,"line":357},[196,888,784],{},[196,890,891],{"class":198,"line":362},[196,892,893],{},"    The Implementation defines the interface for all implementation classes. It\n",[196,895,896],{"class":198,"line":367},[196,897,898],{},"    doesn't have to match the Abstraction's interface. In fact, the two\n",[196,900,901],{"class":198,"line":373},[196,902,903],{},"    interfaces can be entirely different. Typically the Implementation interface\n",[196,905,906],{"class":198,"line":378},[196,907,908],{},"    provides only primitive operations, while the Abstraction defines higher-\n",[196,910,911],{"class":198,"line":384},[196,912,913],{},"    level operations based on those primitives.\n",[196,915,916],{"class":198,"line":389},[196,917,784],{},[196,919,920],{"class":198,"line":394},[196,921,209],{"emptyLinePlaceholder":208},[196,923,924],{"class":198,"line":399},[196,925,926],{},"    @abstractmethod\n",[196,928,929],{"class":198,"line":405},[196,930,931],{},"    def operation_implementation(self) -> str:\n",[196,933,934],{"class":198,"line":410},[196,935,936],{},"        pass\n",[196,938,939],{"class":198,"line":415},[196,940,209],{"emptyLinePlaceholder":208},[196,942,943],{"class":198,"line":420},[196,944,945],{},"\"\"\"\n",[196,947,948],{"class":198,"line":425},[196,949,950],{},"Each Concrete Implementation corresponds to a specific platform and implements\n",[196,952,953],{"class":198,"line":430},[196,954,955],{},"the Implementation interface using that platform's API.\n",[196,957,958],{"class":198,"line":436},[196,959,945],{},[196,961,962],{"class":198,"line":442},[196,963,209],{"emptyLinePlaceholder":208},[196,965,966],{"class":198,"line":448},[196,967,968],{},"class ConcreteImplementationA(Implementation):\n",[196,970,971],{"class":198,"line":454},[196,972,931],{},[196,974,975],{"class":198,"line":460},[196,976,977],{},"        return \"ConcreteImplementationA: Here's the result on the platform A.\"\n",[196,979,980],{"class":198,"line":465},[196,981,209],{"emptyLinePlaceholder":208},[196,983,984],{"class":198,"line":471},[196,985,986],{},"class ConcreteImplementationB(Implementation):\n",[196,988,989],{"class":198,"line":476},[196,990,931],{},[196,992,993],{"class":198,"line":482},[196,994,995],{},"        return \"ConcreteImplementationB: Here's the result on the platform B.\"\n",[196,997,998],{"class":198,"line":487},[196,999,209],{"emptyLinePlaceholder":208},[196,1001,1002],{"class":198,"line":492},[196,1003,1004],{},"def client_code(abstraction: Abstraction) -> None:\n",[196,1006,1007],{"class":198,"line":497},[196,1008,784],{},[196,1010,1011],{"class":198,"line":503},[196,1012,1013],{},"    Except for the initialization phase, where an Abstraction object gets linked\n",[196,1015,1016],{"class":198,"line":509},[196,1017,1018],{},"    with a specific Implementation object, the client code should only depend on\n",[196,1020,1021],{"class":198,"line":514},[196,1022,1023],{},"    the Abstraction class. This way the client code can support any abstraction-\n",[196,1025,1026],{"class":198,"line":520},[196,1027,1028],{},"    implementation combination.\n",[196,1030,1031],{"class":198,"line":525},[196,1032,784],{},[196,1034,1035],{"class":198,"line":531},[196,1036,209],{"emptyLinePlaceholder":208},[196,1038,1039],{"class":198,"line":536},[196,1040,1041],{},"    # ...\n",[196,1043,1044],{"class":198,"line":542},[196,1045,209],{"emptyLinePlaceholder":208},[196,1047,1048],{"class":198,"line":547},[196,1049,1050],{},"    print(abstraction.operation(), end=\"\")\n",[196,1052,1053],{"class":198,"line":552},[196,1054,209],{"emptyLinePlaceholder":208},[196,1056,1057],{"class":198,"line":557},[196,1058,1041],{},[196,1060,1061],{"class":198,"line":563},[196,1062,209],{"emptyLinePlaceholder":208},[196,1064,1065],{"class":198,"line":568},[196,1066,1067],{},"if __name__ == \"__main__\":\n",[196,1069,1070],{"class":198,"line":573},[196,1071,784],{},[196,1073,1074],{"class":198,"line":578},[196,1075,1076],{},"    The client code should be able to work with any pre-configured abstraction-\n",[196,1078,1079],{"class":198,"line":584},[196,1080,1028],{},[196,1082,1083],{"class":198,"line":589},[196,1084,784],{},[196,1086,1087],{"class":198,"line":594},[196,1088,209],{"emptyLinePlaceholder":208},[196,1090,1091],{"class":198,"line":599},[196,1092,1093],{},"    implementation = ConcreteImplementationA()\n",[196,1095,1096],{"class":198,"line":604},[196,1097,1098],{},"    abstraction = Abstraction(implementation)\n",[196,1100,1101],{"class":198,"line":610},[196,1102,1103],{},"    client_code(abstraction)\n",[196,1105,1106],{"class":198,"line":616},[196,1107,209],{"emptyLinePlaceholder":208},[196,1109,1110],{"class":198,"line":622},[196,1111,1112],{},"    print(\"\\n\")\n",[196,1114,1115],{"class":198,"line":628},[196,1116,209],{"emptyLinePlaceholder":208},[196,1118,1119],{"class":198,"line":633},[196,1120,1121],{},"    implementation = ConcreteImplementationB()\n",[196,1123,1124],{"class":198,"line":639},[196,1125,1126],{},"    abstraction = ExtendedAbstraction(implementation)\n",[196,1128,1129],{"class":198,"line":644},[196,1130,1103],{},[37,1132,1134],{"id":1133},"diğer-tasarım-kalıplarıdesign-patterns","Diğer Tasarım Kalıpları\u002FDesign Patterns",[11,1136,1137],{},[44,1138,1139],{},"Oluşumsal Kalıplar (Creational Patterns)",[11,1141,1142,1146,1147,1146,1150,1146,1153,1146,1157],{},[15,1143,1145],{"href":1144},"\u002Ftr\u002Ftasarim-kaliplari-design-patterns-factory-method-nedir","Factory Method",",\n",[15,1148,169],{"href":1149},"\u002Ftr\u002Ftasarim-kaliplari-design-patterns-abstract-factory-nedir",[15,1151,175],{"href":1152},"\u002Ftr\u002Fbuilder-tasarim-deseni-nedir",[15,1154,1156],{"href":1155},"\u002Ftr\u002Fprototype-tasarim-deseni-nedir","Prototype",[15,1158,1160],{"href":1159},"\u002Ftr\u002Fsingleton-tasarim-deseni-nedir","Singleton",[11,1162,1163],{},[44,1164,1165],{},"Yapısal Kalıplar (Structural Patterns)",[11,1167,1168,1146,1172,1146,1175,1146,1179,1146,1183,1146,1187,1146,1191],{},[15,1169,1171],{"href":1170},"\u002Ftr\u002Fadapter-tasarim-deseni-nedir","Adapter",[15,1173,46],{"href":1174},"\u002Ftr\u002Fbridge-tasarim-deseni-nedir",[15,1176,1178],{"href":1177},"\u002Ftr\u002Fcomposite-tasarim-deseni-nedir","Composite",[15,1180,1182],{"href":1181},"\u002Ftr\u002Fdecorator-tasarim-deseni-nedir","Decorator",[15,1184,1186],{"href":1185},"\u002Ftr\u002Ffacade-tasarim-deseni-nedir","Facade",[15,1188,1190],{"href":1189},"\u002Ftr\u002Fflyweight-tasarim-deseni-nedir","Flyweight",[15,1192,1194],{"href":1193},"\u002Ftr\u002Fproxy-tasarim-deseni-nedir","Proxy",[11,1196,1197],{},[44,1198,1199],{},"Davranışsal Kalıplar (Behavioral Patterns)",[11,1201,1202,1146,1206,1146,1210,1146,1214,1146,1218,1146,1222,1146,1226,1146,1230,1146,1234,1146,1238],{},[15,1203,1205],{"href":1204},"\u002Ftr\u002Fchain-of-responsibility-deseni-nedir","Chain of Responsibility",[15,1207,1209],{"href":1208},"\u002Ftr\u002Fcommand-tasarim-deseni-nedir","Command",[15,1211,1213],{"href":1212},"\u002Ftr\u002Fiterator-tasarim-deseni-nedir","Iterator",[15,1215,1217],{"href":1216},"\u002Ftr\u002Fmediator-tasarim-deseni-nedir","Mediator",[15,1219,1221],{"href":1220},"\u002Ftr\u002Fmemento-tasarim-deseni-nedir","Memento",[15,1223,1225],{"href":1224},"\u002Ftr\u002Fobserver-tasarim-deseni-nedir","Observer",[15,1227,1229],{"href":1228},"\u002Ftr\u002Fstate-tasarim-deseni-nedir","State",[15,1231,1233],{"href":1232},"\u002Ftr\u002Fstrategy-tasarim-deseni-nedir","Strategy",[15,1235,1237],{"href":1236},"\u002Ftr\u002Ftemplate-method-tasarim-deseni-nedir","Template Method",[15,1239,1241],{"href":1240},"\u002Ftr\u002Fvisitor-tasarim-deseni-nedir","Visitor",[1243,1244,1245],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":84,"searchDepth":205,"depth":205,"links":1247},[1248,1249,1250,1251,1252,1253,1254],{"id":39,"depth":205,"text":40},{"id":50,"depth":205,"text":51},{"id":94,"depth":205,"text":95},{"id":115,"depth":205,"text":116},{"id":146,"depth":205,"text":147},{"id":182,"depth":205,"text":183},{"id":1133,"depth":205,"text":1134},[1256],"technical",null,"2021-08-23","Bu yazı Design Patterns\u002FTasarım Desenleri nedir? başlıklı yazı dizisinin bir parçasıdır.",false,"md","\u002Fimages\u002Fposts\u002F2021\u002F08\u002Fbridge1.avif","tr",{},{"title":6,"description":1259},"bridge-tasarim-deseni-nedir","tr\u002Fbridge-tasarim-deseni-nedir",[1269,1270],"design-pattern","ipucu","0HWDVL-NG5Y6qvpnltJV6OKg8Gbz9EKRR-4kaJb2dzE",{"prev":1273,"next":1276,"others":1278,"lucky":1387,"readingTime":229},{"path":1274,"title":1275},"\u002Ftr\u002Fearly-return-erken-donus-nedir","Early Return \u002F Erken Dönüş nedir?",{"path":1170,"title":1277},"Adapter Tasarım Deseni Nedir?",[1279,1282,1285,1287,1289,1290,1292,1295,1298,1300,1303,1306,1309,1311,1314,1317,1320,1323,1325,1328,1331,1334,1336,1338,1341,1344,1347,1350,1353,1356,1359,1362,1364,1367,1370,1373,1376,1378,1381,1384],{"path":1280,"title":1281},"\u002Ftr\u002Fmerhaba-phalcon-framework","Merhaba Phalcon Framework",{"path":1283,"title":1284},"\u002Ftr\u002Fwindows-10-golang-kurulumu","Windows 10 ve 11'de Golang Kurulumu ve GOPATH Yapılandırması",{"path":1240,"title":1286},"Visitor Tasarım Deseni Nedir?",{"path":1236,"title":1288},"Template Method Tasarım Deseni Nedir?",{"path":1274,"title":1275},{"path":1232,"title":1291},"Strategy Tasarım Deseni Nedir?",{"path":1293,"title":1294},"\u002Ftr\u002Fes14-nedir-ecmascript-2023-nedir","ES14 nedir? ECMAScript 2023 nedir?",{"path":1296,"title":1297},"\u002Ftr\u002Fes6-nedir-ecmascript-2015-nedir","ES6 Nedir? ECMAScript 2015 Nedir?",{"path":1177,"title":1299},"Composite Tasarım Deseni Nedir?",{"path":1301,"title":1302},"\u002Ftr\u002Fes10-nedir-ecmascript-2019-nedir","ES10 Nedir? ECMAScript 2019 Nedir?",{"path":1304,"title":1305},"\u002Ftr\u002Fgoda-iota-nedir-iota-ne-zaman-ve-nerede-kullanilir","Go'da iota Nedir? iota Ne Zaman ve Nerede Kullanılır?",{"path":1307,"title":1308},"\u002Ftr\u002Frestful-api-bilesenleri","RESTful API Bileşenleri",{"path":1181,"title":1310},"Decorator Tasarım Deseni Nedir?",{"path":1312,"title":1313},"\u002Ftr\u002Fapi-gateway-nedir","API Gateway Nedir? Ne İşe Yarar?",{"path":1315,"title":1316},"\u002Ftr\u002Fgo-veri-tipleri-struct","Go Veri Tipleri: Struct",{"path":1318,"title":1319},"\u002Ftr\u002Frestapi-ve-hateoas-kavrami","RestApi ve HATEOAS Kavramı",{"path":1321,"title":1322},"\u002Ftr\u002Fmutable-ve-immutable-kavrami","Mutable ve Immutable Kavramları Nedir?",{"path":1189,"title":1324},"Flyweight Tasarım Deseni Nedir?",{"path":1326,"title":1327},"\u002Ftr\u002Fecmascript-nedir-ecmascript-ne-degildir-bilinmesi-gerekenler","ECMAScript Nedir? Bilinmesi Gerekenler...",{"path":1329,"title":1330},"\u002Ftr\u002Frest-api-tasarimi","REST API Tasarım İncelikleri",{"path":1332,"title":1333},"\u002Ftr\u002Fdocker-nedir","Docker Nedir?",{"path":1212,"title":1335},"Iterator Tasarım Deseni Nedir?",{"path":1185,"title":1337},"Facade Tasarım Deseni Nedir?",{"path":1339,"title":1340},"\u002Ftr\u002Fcodeserver-nedir-codeserver-nasil-kurulur","Code-Server Nedir? Bulutta VS Code Geliştirme Ortamı Kurulumu",{"path":1342,"title":1343},"\u002Ftr\u002Ftailwind-css-just-in-time-modu","Tailwind CSS Just-in-Time (JIT) Modu Nedir?",{"path":1345,"title":1346},"\u002Ftr\u002Fphp-ve-makine-ogrenimi-php-ml-kutuphanesi","PHP ve Makine Öğrenimi: PHP-ML Kütüphanesi ile Pratik Çözümler",{"path":1348,"title":1349},"\u002Ftr\u002Fes7-nedir-ecmascript-2016-nedir","ES7 Nedir? ECMAScript 2016 Nedir?",{"path":1351,"title":1352},"\u002Ftr\u002Ftricolor-garbage-collection-algoritmasi-nedir","Tricolor Garbage Collection Algoritması Nedir?",{"path":1354,"title":1355},"\u002Ftr\u002Fes11-nedir-ecmascript-2020-nedir","ES11 Nedir? ECMAScript 2020 Nedir?",{"path":1357,"title":1358},"\u002Ftr\u002Fgo-veri-tipleri-map","Go Veri Tipleri - Map",{"path":1360,"title":1361},"\u002Ftr\u002Fes13-nedir-ecmascript-2022-nedir","ES13 nedir? ECMAScript 2022 nedir?",{"path":1208,"title":1363},"Command Tasarım Deseni Nedir?",{"path":1365,"title":1366},"\u002Ftr\u002Flinuxda-golang-kurulumu","Linux'ta Golang Kurulumu",{"path":1368,"title":1369},"\u002Ftr\u002Fwsl-2-kurulumu-6-kolay-adim","WSL 2 Kurulumu - 6 kolay adım",{"path":1371,"title":1372},"\u002Ftr\u002Fes8-nedir-ecmascript-2017-nedir","ES8 Nedir? ECMAScript 2017 Nedir?",{"path":1374,"title":1375},"\u002Ftr\u002Fprogralama-ipucu-yoda-gosterimi","Yoda Koşulları (Yoda Conditions) Nedir? Programlama İpucu",{"path":17,"title":1377},"Design Patterns \u002F Tasarım Desenleri nedir?",{"path":1379,"title":1380},"\u002Ftr\u002Fes16-nedir-ecmascript-2025-nedir","ES16 nedir? ECMAScript 2025 nedir?",{"path":1382,"title":1383},"\u002Ftr\u002Fgo-ve-degiskenler","Go ve Değişkenler",{"path":1385,"title":1386},"\u002Ftr\u002Flitespeed-web-server-performans-artisi","Konfor Alanından Çıkıp, Konforlu Bir VPS'e Geçmek: LiteSpeed Web Server",{"path":1388,"title":1389},"\u002Ftr\u002Fubuntu-guncellemesi-sonrasi-cyberpanele-ulasilamama-sorunlarini-giderme","Ubuntu Güncellemesi Sonrası CyberPanel'e Ulaşılamama Sorunlarını Giderme",[1391,1393,1395,1397],{"path":1240,"title":1286,"date":1392},"2021-10-09",{"path":1236,"title":1288,"date":1394},"2021-10-08",{"path":1232,"title":1291,"date":1396},"2021-10-07",{"path":1228,"title":1398,"date":1399},"State Tasarım Deseni Nedir?","2021-10-06",[1401,1403,1405],{"path":1326,"title":1327,"date":1402},"2021-10-20",{"path":1332,"title":1333,"date":1404},"2021-01-06",{"path":1406,"title":1407,"date":1408},"\u002Ftr\u002Fubuntu-20-04-composer-kurulumu","Ubuntu 20.04 - Composer Kurulumu","2021-02-21",1782142081951]