Köprüler Kurarak Esneklik Kazanın: Bridge Tasarım Kalıbı İle Çözümlemeler ve Dört Farklı Dilde Uygulamalar

[en] Read in English

2023-06-22

Bir zamanlar, iki krallık varmış. Bu krallıklar birbirlerine çok yakın olmasına rağmen, aralarında geniş ve derin bir nehir bulunuyormuş. Bu nehir, krallıkların birbirleriyle etkileşim kurmasını zorlaştırıyormuş. Bu durumu çözmek için, her iki krallık da bir köprü inşa etmeye karar vermiş.

Bu köprü, iki krallık arasında iletişimi sağlayan bir arayüz olmuş. Ancak, köprünün her iki tarafında farklı yapılar ve özellikler bulunuyormuş. Bir taraf taştan, diğer taraf ise ahşaptan yapılmış. Bu durum, köprünün her iki tarafının birbirinden bağımsız olarak değiştirilebilmesini sağlamış. Yani, bir tarafın yapısını değiştirmek, diğer tarafı etkilemiyormuş. Bu, köprünün esnekliğini ve genişletilebilirliğini artırmış.

İşte bu hikaye, Bridge tasarım kalıbının temel fikrini temsil eder. Bridge kalıbı, bir uygulamanın farklı parçalarının birbirinden bağımsız olarak değiştirilebilmesini sağlar. Bu, uygulamanın daha esnek ve genişletilebilir olmasını sağlar.

Bridge Pattern Class Diagram

C# Örneği:

interface IDrawAPI
{
    void DrawCircle(int radius, int x, int y);
}

public class RedCircle : IDrawAPI
{
    public void DrawCircle(int radius, int x, int y)
    {
        Console.WriteLine("Drawing Circle[ color: red, radius: " + radius + ", x: " + x + ", " + y + "]");
    }
}

public class GreenCircle : IDrawAPI
{
    public void DrawCircle(int radius, int x, int y)
    {
        Console.WriteLine("Drawing Circle[ color: green, radius: " + radius + ", x: " + x + ", " + y + "]");
    }
}

abstract class Shape
{
    protected IDrawAPI drawAPI;
    protected Shape(IDrawAPI drawAPI)
    {
        this.drawAPI = drawAPI;
    }
    public abstract void Draw();
}

public class Circle : Shape
{
    private int x, y, radius;

    public Circle(int x, int y, int radius, IDrawAPI drawAPI) : base(drawAPI)
    {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public override void Draw()
    {
        drawAPI.DrawCircle(radius,x,y);
    }
}

Java Örneği:

interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

public class RedCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {


```java
      System.out.println("Drawing Circle[ color: red, radius: " + radius + ", x: " + x + ", " + y + "]");
   }
}

public class GreenCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: green, radius: " + radius + ", x: " + x + ", " + y + "]");
   }
}

abstract class Shape {
   protected DrawAPI drawAPI;
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();  
}

public class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }

   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

Go Örneği:

package main

import "fmt"

type DrawAPI interface {
   drawCircle(radius int, x int, y int) 
}

type RedCircle struct {}

func (r *RedCircle) drawCircle(radius int, x int, y int) {
   fmt.Printf("Drawing Circle[ color: red, radius: %d, x: %d, y: %d]\n", radius, x, y)
}

type GreenCircle struct {}

func (g *GreenCircle) drawCircle(radius int, x int, y int) {
   fmt.Printf("Drawing Circle[ color: green, radius: %d, x: %d, y: %d]\n", radius, x, y)
}

type Shape struct {
   drawAPI DrawAPI
}

type Circle struct {
   x int
   y int
   radius int
   drawAPI DrawAPI
}

func (c *Circle) draw() {
   c.drawAPI.drawCircle(c.radius, c.x, c.y)
}

Rust Örneği:

trait DrawAPI {
    fn draw_circle(&self, radius: i32, x: i32, y: i32);
}

struct RedCircle;

impl DrawAPI for RedCircle {
    fn draw_circle(&self, radius: i32, x: i32, y: i32) {
        println!("Drawing Circle[ color: red, radius: {}, x: {}, y: {}]", radius, x, y);
    }
}

struct GreenCircle;

impl DrawAPI for GreenCircle {
    fn draw_circle(&self, radius: i32, x: i32, y: i32) {
        println!("Drawing Circle[ color: green, radius: {}, x: {}, y: {}]", radius, x, y);
    }
}

struct Circle {
    x: i32,
    y: i32,
    radius: i32,
    draw_api: Box<dyn DrawAPI>,
}

impl Circle {
    fn new(x: i32, y: i32, radius: i32, draw_api: Box<dyn DrawAPI>) -> Circle {
        Circle { x, y, radius, draw_api }
    }

    fn draw(&self) {
        self.draw_api.draw_circle(self.radius, self.x, self.y);
    }
}

Bu örnekler, Bridge tasarım kalıbının nasıl uygulanabileceğini gösterir. Her birinde, DrawAPI adında bir arayüz (veya Rust’ta bir trait) ve bu arayüzü uygulayan iki sınıf (`RedCircle

ve GreenCircle) bulunmaktadır. Shape ve Circle sınıfları, bu arayüzü kullanarak çizim işlemlerini gerçekleştirir. Bu sayede, çizim işlemlerinin nasıl gerçekleştirileceği (RedCircle veya GreenCircle kullanılarak) Shape ve Circle sınıflarından bağımsız hale gelir.

Bridge tasarım kalıbını kullanmanın birçok nedeni vardır. İşte en önemli sebepler:

  1. Bağımsızlık: Bridge tasarım kalıbı, bir uygulamanın farklı parçalarının birbirinden bağımsız olarak değiştirilebilmesini sağlar. Bu, bir parçanın değiştirilmesinin diğer parçaları etkilememesi anlamına gelir.

  2. Esneklik: Bridge tasarım kalıbı, uygulamanın daha esnek olmasını sağlar. Bu, uygulamanın farklı gereksinimlere ve durumlara kolayca adapte olabilmesi anlamına gelir.

  3. Genişletilebilirlik: Bridge tasarım kalıbı, uygulamanın genişletilebilir olmasını sağlar. Bu, yeni özelliklerin veya işlevlerin kolayca eklenmesi anlamına gelir.

  4. Kod tekrar kullanımı: Bridge tasarım kalıbı, kodun tekrar kullanılmasını kolaylaştırır. Bu, aynı kodun farklı yerlerde tekrar tekrar kullanılabilmesi anlamına gelir, bu da kodun daha kısa ve daha anlaşılır olmasını sağlar.

  5. Ayırma ve Organizasyon: Bridge tasarım kalıbı, kodun daha iyi organize edilmesini ve ayırılmasını sağlar. Bu, kodun daha kolay okunabilir ve bakımının daha kolay olması anlamına gelir.

  6. Dinamik Bağlama: Bridge tasarım kalıbı, dinamik bağlama kullanır. Bu, uygulamanın çalışma zamanında farklı implementasyonları seçebilmesi anlamına gelir.



Bu gibi daha fazla gönderi...

Bileşenlerin Dansı: Composite Tasarım Kalıbı

2023-06-22 | #composite-pattern #design-patterns #structural-patterns

Bir zamanlar, bir ormanda bir ağaç vardı. Bu ağaç, yaprakları ve dalları olan karmaşık bir yapıydı. Her dalın üzerinde daha küçük dallar ve yapraklar bulunabilirdi. Ağaç, dallarını ve yapraklarını bir arada tutan bir bütün olarak çalışıyordu. Bu ağaç, Composite tasarım kalıbının bir örneğidir. Ağaç (Composite), dallar (yine Composite) ve yapraklar (Leaf) olmak üzere iki tür bileşen içerir. Hem dallar hem de yapraklar, ağaç tarafından tanınan aynı arayüzü (Component) uygular. Bu sayede ağaç, dallarını ve yapraklarını aynı şekilde işleyebilir.

Devamı 


Dekoratör Tasarım Deseni: Yazılımın Süsleyicileri

2023-06-15 | #decorator-pattern #design-patterns #structural-patterns

Bir zamanlar, bir “Component” adında bir nesne varmış. Bu nesne, belirli bir işlevi yerine getirmek için kullanılırmış. Ancak, bazen bu işlevi genişletmek veya değiştirmek gerekiyormuş. İşte bu noktada “Decorator"lar devreye giriyormuş. Decorator’lar, Component’i “süsleyen” veya genişleten nesnelerdir. Bir Decorator, bir Component’in üzerine gelir ve onun işlevini genişletir veya değiştirir. Bu, Component’in kendisini değiştirmeden, onun işlevselliğini genişletmek için kullanılır. Örneğin, bir “TextComponent” düşünün. Bu component, bir metni ekrana yazdırır. Ancak, bazen metni kalın veya italik yapmak isteyebiliriz.

Devamı 


Kodun Dilinden Masallar: Adapter Pattern ile Farklı Dünyaları Birleştirmek

2023-06-15 | #adapter-pattern #design-patterns #structural-patterns

Bir zamanlar, iki farklı dünyadan gelen iki arkadaş vardı: Elektrikli Süpürge ve Elektrik Prizi. Elektrikli Süpürge, enerjiye ihtiyaç duyuyordu ve bu enerjiyi Elektrik Prizinden almak istiyordu. Ancak bir sorun vardı. Elektrikli Süpürge’nin fişi, Elektrik Prizi’ne uymuyordu. İkisi de farklı standartlarda üretilmişti ve birbiriyle doğrudan iletişim kuramıyorlardı. Bu durumda, bir kahraman ortaya çıktı: Adaptör. Adaptör, Elektrikli Süpürge’nin fişi ile Elektrik Prizi arasında bir köprü oluşturdu. Elektrikli Süpürge’nin fişini Adaptör’ün bir tarafına takıldı ve Adaptör’ün diğer tarafı Elektrik Prizi’ne takıldı.

Devamı 