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.
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:
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.