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

[en] Read in English

2023-06-15

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. İşte bu noktada “BoldDecorator” veya “ItalicDecorator” devreye girer. Bu decorator’lar, TextComponent’in üzerine gelir ve metni kalın veya italik yaparlar.

Decorator pattern, bu şekilde çalışır. Bir component ve onu genişleten bir dizi decorator ile, çok çeşitli işlevleri gerçekleştirebiliriz.

İşte decorator pattern’ın bir sınıf diyagramı:

Decorator Pattern Class Diagram

Bu diyagramda, bir “Component” ve bu component’i süsleyen veya genişleten bir dizi “Decorator” görebilirsiniz. “ConcreteComponent” sınıfı, “Component” sınıfını genişletir ve belirli bir işlevi yerine getirir. “Decorator” sınıfı da “Component” sınıfını genişletir ve bir “Component” nesnesini içerir. “ConcreteDecoratorA” ve “ConcreteDecoratorB” sınıfları, “Decorator” sınıfını genişletir ve belirli bir işlevi yerine getirir.

Öncelikle, C# dilinde bir örnek vereceğim:

// Component
public abstract class Component
{
    public abstract void Operation();
}

// ConcreteComponent
public class ConcreteComponent : Component
{
    public override void Operation()
    {
        // ...
    }
}

// Decorator
public abstract class Decorator : Component
{
    protected Component component;

    public Decorator(Component component)
    {
        this.component = component;
    }

    public override void Operation()
    {
        if (component != null)
        {
            component.Operation();
        }
    }
}

// ConcreteDecoratorA
public class ConcreteDecoratorA : Decorator
{
    public ConcreteDecoratorA(Component component) : base(component) { }

    public override void Operation()
    {
        base.Operation();
        // Additional behavior
    }
}

// ConcreteDecoratorB
public class ConcreteDecoratorB : Decorator
{
    public ConcreteDecoratorB(Component component) : base(component) { }

    public override void Operation()
    {
        base.Operation();
        // Additional behavior
    }
}

Bu kodda, bir “Component” ve bu component’i süsleyen veya genişleten bir dizi “Decorator” oluşturduk. “ConcreteComponent” sınıfı, “Component” sınıfını genişletir ve belirli bir işlevi yerine getirir. “Decorator” sınıfı da “Component” sınıfını genişletir ve bir “Component” nesnesini içerir. “ConcreteDecoratorA” ve “ConcreteDecoratorB” sınıfları, “Decorator” sınıfını genişletir ve belirli bir işlevi yerine getirir.

Java:

// Component
public interface Component {
    void operation();
}

// ConcreteComponent
public class ConcreteComponent implements Component {
    public void operation() {
        // ...
    }
}

// Decorator
public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        if (component != null) {
            component.operation();
        }
    }
}

// ConcreteDecoratorA
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // Additional behavior
    }
}

// ConcreteDecoratorB
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        // Additional behavior
    }
}

Go:

// Component
type Component interface {
    Operation() string
}

// ConcreteComponent
type ConcreteComponent struct{}

func (c *ConcreteComponent) Operation() string {
    return "ConcreteComponent"
}

// Decorator
type Decorator struct {
    component Component
}

func (d *Decorator) Operation() string {
    if d.component != null {
        return d.component.Operation()
    }
    return ""
}

// ConcreteDecoratorA
type ConcreteDecoratorA struct {
    Decorator
}

func (c *ConcreteDecoratorA) Operation() string {
    return "ConcreteDecoratorA(" + c.Decorator.Operation() + ")"
}

// ConcreteDecoratorB
type ConcreteDecoratorB struct {
    Decorator
}

func (c *ConcreteDecoratorB) Operation() string {
    return "ConcreteDecoratorB(" + c.Decorator.Operation() + ")"
}

Rust:

// Component
trait Component {
    fn operation(&self) -> String;
}

// ConcreteComponent
struct ConcreteComponent;

impl Component for ConcreteComponent {
    fn operation(&self) -> String {
        String::from("ConcreteComponent")
    }
}

// Decorator
struct Decorator<T: Component> {
    component: T,
}

impl<T: Component> Component for Decorator<T> {
    fn operation(&self) -> String {
        self.component.operation()
    }
}

// ConcreteDecoratorA
struct ConcreteDecoratorA<T: Component> {
    decorator: Decorator<T>,
}

impl<T: Component> Component for ConcreteDecoratorA<T> {
    fn operation(&self) -> String {
        let base_operation = self.decorator.operation();
        format!("ConcreteDecoratorA({})", base_operation)
    }
}

// ConcreteDecoratorB
struct ConcreteDecoratorB<T: Component> {
    decorator: Decorator<T>,
}

impl<T: Component> Component for ConcreteDecoratorB<T> {
    fn operation(&self) -> String {
        let base_operation = self.decorator.operation();
        format!("ConcreteDecoratorB({})", base_operation)
    }
}

Bu örnekler, decorator pattern’ın farklı dillerde nasıl uygulanabileceğini gösterir. Her dilin kendi özelliklerine ve sözdizimine sahip olduğunu unutmayın, bu yüzden her dil için örnekler biraz farklı olabilir.



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ı 


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

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

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ış.

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ı 