Tasarım Örüntüleri

Builder Pattern

Creational Patterns bir örneği olan Builder Pattern bize kompleks nesneleri oluşturmakta zorlandığımız durumlarda nasıl bu işlemi kolaylaştırabileceğimiz konusunda bir yaklaşım sunar.

Onur Dayıbaşı
Design Patterns

--

Bilgi Notu: Diğer tüm Tasarım Örüntüleri yazıma bu linkten ulaşabilirsiniz.

Hangi Durumda

Aşağıdaki sınıfı incelediğimizde 4 tane özelliği bulunuyor. Bunlar x,y,width, height. 4 tane özelliği bu nesnenin anlamlı olması için gerekli. Bu durumda bu nesne için 1 tane constructor yeterli olacaktır.

class Rect
public Rect(int x, int y, int width,int height) //Constructor

Bu tarz Rect gibi oluşturulması basit yani 1,2 constructor oluşturarak nesneyi oluşturabiliyorsanız bunlara oluşturulması basit nesneler diyebiliriz.

Ama bazı nesneler vardır ki bunların çok fazla parametresi bulunur. Ve bunlardan x1,x3 ile başka nesne görünümü oluşturulurken, x4,x5 ile başka bir nesne görüntüsü oluşturulabilir durumların sayısı çok arttığında tüm kombinasyonları karşılayacak bir constructor oluşturmak oldukça zor olur.

class Complex
int x1,x2,x3,x4 ...................
constructor1(x1, x2)
constructor2(x3, x4)
constructor3(x5, x1)
.....

Örneğin bir SQL cümlesi oluşturacaksınız Select her zaman olacak ama Where olmak durumunda değil, GroupBy olmak durumunda değil vb…

Örneğin bir yemek sipariş nesneniz var. İstenilen yemek parçalarına göre Hamburger, Patates, Kola olsun veya yanında İçecek olmasın gibi nesnenizin farklı farkı görüntüleri olabilir

Bu durumda bir diğer yöntem boş/default constructor ile sınıfı oluşturup bu nesneye set veya add gibi metodlar ile oluşturabilirsiniz.

class Complex
setX1()
setX2()
setX3()
setX4()

Bu durumda sınıfınız bir çok set metodu oluşacaktır. Örneğin bir Sipariş bilgisini aşağıdaki şekilde yazalım.

//Sipariş Oluşturma işlemi 
Order order=new Order();
order.addHamburger(type, count)
order.addDrink(type, count)
order.addPizza(type, count)
......

Burada kodu yazarken sipariş oluşturma işi bir bütün olarak gözükmez. Çünkü geliştirici arada başka başka işlemlerde yapabilir

//Sipariş Oluşturma işlemi 
Order order=new Order();
order.addHamburger(type, count)
order.addDrink(type, count)
sum = 3+2;
callFunction()
order.addPizza(type, count)
......

Avantajları

Ama bunu Builder Pattern ile yazdığımızda her kendi basit DSL(Domain Specific Language) oluşturacak this döneceği için daha odaklı bir nesne oluşturma yapısı oluşturabiliriz.

Nested Builder

new Order.Builder().hamburger(ABurger,2).drink(BDrink,1).build()

Peki bunu nasıl gerçekleştireceğiz. Kompleks nesnemizin içerisine bunun üretilmesinden sorumlu bir Builder objesi olacak bu bizim Burada kompleks nesne oluşturma mantığını nesnenin kendi kendi içerisindeki bulunan Builder

public class Order
ArrayList<Enum,int> hamburgers
ArrayList<Enum,int> drinks
ArrayList<Enum,int> pizza
public static class OrderBuilder
//return this
public OrderBuilder hamburger(type, count){}
public OrderBuilder drink(type, count){}
public OrderBuilder pizza(type, count){}
//return Order
public buid(){ return new Order()..}

Not: Burada Order default constructor private hale getirmek , set metodlarını dışarıya kapatmak bu kompleks nesnenin olabildiğince kontrollü oluşmasını sağlayacaktır.

Builder Pattern Yapısı

Builder Pattern Class Diagram

Diğer bir yöntemde Product türünü oluşturabilecek ara Builder interface gerçekleştirmiş sınıflar farklı türdeki nesneleri oluşturma adımlarını kendi içlerinde saklar ve buna göre oluştururlar.

Örneğin aşağıda Araba nesneleri oluşturmak isteyelim. Ferrari, Opel, Mercedes, BMW, WV vb.. türlerde oluşturmak.

Builder Pattern from wikipedia

Car : Arabamızın Markası, Modeli, KapıSayısı ve Rengi var.
ICarBuilder : Araç oluşturma arayüzü Renk ve Araç Kapısını değişken olarak alıyor
FerrariBuilder : Aracın Markası, Modeli zaten bu sınıf biliyor. Burda bir takım kendi sınıfına özel koşullarıda içeriyor olabilir örneğin Kapı sayısı limitleri vardır set ettirmez gibi … Ve biz BMWBuilder, MercedesBuilder vb.. bu sınıfları arttırabiliriz.

SportsCarBuildDirector: Kendisine gelen araçlara belki bir servisten aldığı , belki kullanıcı arayüzünden aldığı Renk ve Kapı sayısı değerini set etmekten sorumludur.

Client : Tüm bu süreci yöneten sınıf.

Değişiklik İhtiyaçlarını Nasıl Karşılayacak

  • Yeni bir Araç türü geldiğinde bu yapıyı değiştirmeden tek bir sınıf ekleyerek bu yapımızı genişletebiliriz.
  • İlgili araç özelinde bir kısıtlama geldiğinde ortak yapıyı etkilemeyen bir konu ise sadece ilgili sınıfta mantığı değiştirerek sorunu çözebiliriz.
  • Eğer Ortak bir yapıda değişiklik var ise bunun Tüm arayüzlerde değişikliğini bileceğiz ve tüm sistem sınıflarında güncelleme yaparak eksik bir nokta bırakmayı engeller.

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--