Design Patterns — Structural

Mert Kimyonşen
5 min readSep 27, 2020

Bir önceki yazı için Design Patterns — Creational

Merhabalar,

Tasarım kalıplarını öğrenemeye devam ediyoruz. Bu yazımda serinin devamı niteliğinde olan Structural Design Patterns (Yapısal Tasarım Kalıpları) inceliyor olacağız.

Tasarım kalıpları;

Nesne yönelimli programlamada; sınıf ve nesneler arasındaki ilişkilerin en iyi şekilde nasıl olmaları gerektiğini açıklayan yöntemlerdir.

Stuctural Design Pattern (Yapısal Tasarım Kalıpları)

İngilizce kelime olan Structural kelimesinin Türke anlamı yapısaldır ve yapısal ise yapıyı ele alan, yapıyı inceleyen anlamına gelmektedir.

Structural Design Patterns, nesneler arasındaki ilişkileri ve bu ilişkileri organize etmek için çözümler sunan tasarım kalıplarından oluşur.

Gof kitabına göre; Structural Patterns 7 adet tasarım kalıplarından oluşur;

  • Adapter Pattern
  • Proxy Pattern
  • Bridge Pattern
  • Facade Pattern
  • Composite Pattern
  • Decorator Pattern
  • Flyweight Pattern

Adapter Pattern

Mevcutta bulunan bir sınıfın kaynak kodları değiştirmeden başka bir sınıf ile entegre çalışabilecek özellik kazandırmak için uygulanan yaklaşımdır. Bu sayede sisteme yeni özelliklerin eklenmesini kazandırır.

Ne zaman kullanmalıyız

  • Birbiriyle uyumsuz/çalışmayan sınıfları çalışabilir hale getirmek istiyorsak.
  • Uyumsuz arayüz sınıfları ile birlikte çalışmak istiyorsak

Kullanım Sıklığı

  • Orta Yüksek

UML Diagram

Proxy Pattern

Proxy kelime anlamı temsilidir. Oluşturduğumuz proxy nesneler üzerinden hedef yani gerçek nesneleri temsil etmemizi sağlar. Bir ağ bağlantısına, bellekte bulunan büyük bir nesneye, bir dosyaya, çoğaltılması pahallı ya da imkansız olan kaynaklara arabirim (interface) oluşturabilir. Kısacası; Proxy nesneleri istemci (client) tarafından çağrıldığında arka planda gerçek nesneye erişmek için sarmallayıcı (wrapper) ya da aracı nesnedir.

Farklı amaçlarla kullanılan proxy tipleri vardır. Bunlardan bazıları;

  1. Remote(Uzak) Proxy: Remote(uzak) bir nesne kullanılacağı durumlarda kullanılır.
  2. Virtual Proxy: İhtiyaç halinde hedef sınıfları oluşturur.
  3. Protection Proxy: Yetkilendirme durumlarında kullanılır.
  4. Logging Proxy: İşlem gerçekleştiği zaman önce ya da sonra log işlemleri için kullanılır.

Ne zaman ihtiyaç duyarız

  • Çalışma maliyeti yüksek işlemlerin olduğu yapılarda maliyeti düşürmek istiyorsak
  • İşlemin gerçekleştirilmesinden önce ya da sonra hazırlık yapılmasını istiyorsak
  • Client ihtiyaç halinde hedef sınıfın oluşmasını istiyorsak
  • Bir nesneye erişimin kontrol etmek istiyorsak
  • Bir nesneye erişirken ek işlevsellik eklemek istiyorsak

Kullanım Sıklığı

  • Orta Yüksek

UML Diagram

  • Subject: Proxy ve RealSubject için bir çatı bir arayüz sağlar.
  • RealSubject: Gerçek nesnemiz
  • ProxySubject: Gerçek nesneyi kapsülleyen ve sarmallayan sınıfımız

Proxy Pattern Kod Örneği

Bridge Pattern

Bir soyutlamayı (abstraction) uygulamasından (implementation) ayırın, böylece ikisi birbirinden bağımsız olarak değişebilir anlamına gelen bir tasarım kalıbıdır. Yani soyut nesneler ile somut nesneler arasında köprü kurar. Bu sayede soyutlamada olan değişim uygulamayı, uygulamada olan değişim soyutlamayı etkilemez. Her ikisi bağımsız olarak geliştirilebilir.

Ne zaman kullanmalıyız

  • Bir soyutlamayı ve onun uygulamasını birbirinden bağımsız olarak tanımlamak ve genişletmek istiyorsak.
  • Arayüzleri clienttan tamamen ayırmak istiyorsak.
  • Arayüzleri direkt olarak clientla iletişime geçen abstractiona bağlamak istemiyorsak.
  • Abstraction classını rebuild dahi etmeden implementasyonlar içerisinde değişiklik yapmak istiyorsak.

Kullanım Sıklığı

  • Orta

UML Diagram

  • Abstraction: Soyut sınıfımız.
  • RefinedAbstraction: Abstraction tarafından uygulanan arayüzü genişletir.
  • Implementor: Uygulama sınıfları için arayüz tanımlar.
  • ConreteImplementor: Implementor arayüzü uygular.

Facade Pattern

  • Karmaşık bir yapıdaki alt sistemi (subsytem) bir üst sistemde bütün olarak sağlayan yapıdır. Yani karmaşık yapıdaki alt sistemi client tarafına daha basit ve yüksek seviyeli bir arayüz sağlar ve bu arayüz çatısı altında alt sistemleri organize bir şekilde yönetir. Burada önemli olan alt sistemlerin birbirinden bağımsız olmasıdır. Ayrıca bu alt sınıflar Facade sınıfından da bağımsız bir şekilde çalışabilmektedir.

Ne zaman kullanmalıyız

  • Alt sistemleri bir üst sistemde toplamak istiyorsak.
  • Karmaşık bir sistemin kullanımını kolaylaştırmak istiyorsak.
  • Alt sistemlere olan bağımlılığın en az seviyeye indirmek istiyorsak
  • Karmaşık yapıları Client tarafından soyutlamak istiyorsak.

Kullanım Sıklığı

  • Yüksek

UML Diagram

  • Facade alt sistemleri bütün olarak uygulayan sınıfımız.

Facade Pattern Kod Örneği

Composite Pattern

Composite Pattern, nesneleri bir ağaç yapısında birleştirip uygulamanın genelindeki parça bütün ilişkisini yeniden düzenleyip şekillendirmektir. Ağaç yapısındaki nesne kalıplarının hiyerarşik olarak iç içe kullanılmasını düzenlemektedir.

Ne zaman kullanmalıyız

  • Basit nesnelerden ve bu basit nesneleri barındıran kompleks objelerden oluşan bir yapı istiyorsak.
  • Client tarafının nesnelerin bir kısmını ya da tamamını aynı şekilde ele almasını istiyorsak.
  • Bütün bir hiyerarşiyi ağaç yapısında temsil etmek istiyorsak

Kullanım sıklığı

  • Orta Yüksek

UML Diagram

Composite Pattern Kod Örneği

Decorator Pattern

Aynı sınıftan oluşan nesnelerin davranışını etkilemeden nesneye dinamik olarak yeni özellik ve sorumluluklar eklenmesi için kullanılan tasarım kalıbıdır. Ayrıca kullanılan özelliğin çıkarılması için de kullanılan tasarım kalıbıdır. Bir nesneyi kendisinden türeyen alt sınıflar ile genişletmek yerine kullanılabilen alternatif yaklaşım sunar.

Ne zaman kullanmalıyız

  • Nesnelere dinamik olarak yeni sorumluluklar yüklemek ve becerilerini artırmak istiyorsak.
  • Alt sınıflara genişletme sağlayarak işlevsel olmasını sağlamak istiyorsak.

Kullanım sıklığı

  • Orta

UML Diagram

Decorator Pattern Kod Örneği

Flyweight Pattern

Benzer nesneleri tekrar tekrar oluşturmak yerine merkezi bir yerden tedarik ederek bellek alanlarının optimize edilmesini için kullanılan bir tasarım kalıbıdır. Bu tasarım kalıbının amacı yapıca aynı nesneleri bellekte çokça oluşturmak yerine her bir nesnenin bir kopyasını oluşturmak ve oluşturulan nesneleri ortak bir noktada tutup paylaştırma işlemini yerine getirmektir. Yani tekrar eden aynı nesneleri gruplayarak hafızada çok fazla yer kaplamaması için hafıza kullanımını minimuma indirmektir.

Ne zaman kullanmalıyız

  • Çok fazla sayıdaki nesneleri verimli bir şekilde kullanmak istiyorsak
  • Benzer nesneleri tekrar tekrar oluşturmak istemiyorsak

Ör: Büyük metin belgesindeki bulunan her bir karakter için bir nesne oluşturmak verimli bir şekilde işlenmeyen çok sayıda nesneye neden olur.

Kullanım sıklığı

  • Düşük

UML Diagram

Flyweight Pattern Kod Örneği

Yapısal tasarım kalıpları hakkında elde ettiğim bilgileri paylaşmaya çalıştım. Umarım faydalı olmuştur.

Bir sonraki yazımda yazmayı planladığım tasarım kalıbı; Behavioral Design Patterns (Davranışsal Tasarım Kalıpları) ve ona bağlı en çok kullanılan bir tasarım kalıbını örnek üzerinde açıklamak olacak.

Sağlıkla kalın!

--

--