15 Aralık 2014 Pazartesi

Gof - Bridge Örüntüsü - İki Farklı Nesne Hiyerarşisi Arasında Köprü Vardır

Not : GoF Tasarım Örüntüleri yazısına bakabilirsiniz.

Bridge - Yapısal Örüntü
Bridge kodlarda çok kullanılsa bile ismi bridge olarak geçmez.  İki farklı nesne hiyerarşisi vardır.  Birinci hiyerarşinin kökü, ikinci hiyerarşinin sadece kök nesnesini bilir ve kullanır . 

Böylece ilk hiyerarşideki kalıtan nesneler de aynı diğer hiyerarşiye erişebilir. Yani ikisi arasında bridge (köprü) kurulur 

Örnek - Notification ve NotificationSender Hiyerarşisi 
Elimizde şöyle bir kod olsun. Burada ilk nesne hiyerarşisi tanımlı ve NotificationSender hiyerarşisini kullanıyor
public abstract class Notification {
  NotificationSender notificationSender; //Bridge olarak kullanılan nesne

  public Notification(NotificationSender notificationSender) {
    this.notificationSender = notificationSender;
  }

  abstract public void send();
}

public class PushNotification extends Notification {
  public PushNotification(NotificationSender notificationSender) {
    super(notificationSender);
  }

  @Override
  public void send() {
    notificationSender.sendNotification();
  }
}

public class TextNotification extends Notification {

  public TextNotification(NotificationSender notificationSender) {
    super(notificationSender);
  }

  @Override
  public void send() {
    notificationSender.sendNotification();
  }
}
İkinci hiyerarşi şöyle olsun
public interface NotificationSender {
    public void sendNotification();
}
public class PushNotificationSender implements NotificationSender {
  @Override
  public void sendNotification() {
    ...
  }
}
public class TextNotificationSender implements NotificationSender {
  @Override
  public void sendNotification() {
    ...
  }
}
Örnek - Foo + OutputStream Hiyerarşisi 
Bu örüntü çıktı vermek için sıkça kullanılır. Elimizde bir nesne hiyerarşisi olur. En tepedeki kök nesnede (root object) bir OutputStream soyut nesnesi olur. OutputStream de kendi içinde kalıtım hiyerarşisine sahiptir. FileOutputStream, ByteBufferOutputStream vs. gibi. Böylece kendi nesne hiyerarşim istediğim herhangi bir tipte çıktı verebilir.

Örnek - Tv ve RemoteControl Hiyerarşisi 
Head First Design Pattern kitabındaki örnek şöyle
"Bridge pattern allows you to vary implementation and the abstraction by placing two in separate class hierarchies. "

Implementation : TV <--  Sony
                              |        |- LG
                           (has)
Abstraction : Remote Control <-- Concrete Remote Control
Burada elimizde bir TV nesne hiyerarşisi var. Her Tv'nin bir RemoteControl nesnesi var. Ancak RemoteControl farklı gerçekleştirimlere sahip olabilir. Bu yüzden TV ve RemoteControl soyut sınıflar. Kendi kalıtım hiyerarşileri var, ancak birbirlerini TV ve RemoteControl seviyesinde biliyorlar.

Örnek - Shape ve Renderer Hiyerarşisi 
Elimizde bir Shape hiyerarşisi olsun. En üstteki Shape nesnesi Renderer hiyerarşisini kullanıyor
abstract class Shape {
    protected Renderer renderer;
    public Shape(Renderer renderer) {
        this.renderer = renderer;
    }
    public abstract void draw();
}

// Concrete Shape Implementations
class Circle extends Shape {
    public Circle(Renderer renderer) {
        super(renderer);
    }
    @Override
    public void draw() {
        System.out.print("Drawing Circle: ");
        renderer.renderShape();
    }
}
class Square extends Shape {
    public Square(Renderer renderer) {
        super(renderer);
    }
    @Override
    public void draw() {
        System.out.print("Drawing Square: ");
        renderer.renderShape();
    }
}
Renderer hiyerarşisi de şöyle olsun
// Implementations
interface Renderer {
    void renderShape();
}
class VectorRenderer implements Renderer {
    @Override
    public void renderShape() {
        System.out.println("Rendering shape in vector format.");
    }
}
class RasterRenderer implements Renderer {
    @Override
    public void renderShape() {
        System.out.println("Rendering shape in raster format.");
    }
}



Hiç yorum yok:

Yorum Gönder