Builder Design Pattern
Builder design patterni farklı şekildeki nesnelerin oluşturulmasında, clientin sadece nesne tipini belirterek creation işlemini gerçekleştirebilmesini sağlamak için kullanılır. Builder design patterninde clientin kullanmak istediği bir ürünün birden fazla şekli olabileceği düşünülür. Farklı şekillerin olduğu nesnenin üretiminden builder pattern sorumludur. Dolayısıyla client bu işten soyutlanır. Builder design pattern yer yer factory pattern yer yer de strategy pattern ile karıştırılmaya müsaittir. Bu sebeple builder tasarım kalıbını ayırabilmek için odaklanmamız gereken cümle ‘ Farklı sunum şekilleri olan nesneler ‘dir. Örnek olarak, Pide nesnesi için Kıymalı Pide, Kaşarlı Pide, Sucuklu Pide… bu nesnenin şekilleridir. Böyle deyince kıymalı bir pidenin kaşarlısını üretmek için tek yapmam gereken bir propertyi değiştirmek ne design patterni gibi düşünebilirsiniz. Biraz daha kompleksleştirirsek, Phone nesnesi için Iphone8, SamsungGalaxy, Huawei… bu nesnenin farklı şekilleridir.
dofactory.com tarafından verilen örnek ile devam edelim. Bu örnekte motorsiklet, otomobil, scooter gibi ürünler söz konusudur. Tüm bu araçların istemci açısından kullanılabilir olması için üretim işleminde motorun(her ne kadar motorsiklette ve scooter’ da kapı olmasada 0 veya null değeri kullanılabilir) , kapıların, viteslerin vb parçalarında üretimi gerekmektedir.
Aslında bu ortak fonksiyonellikler bu ürünlerin hepsi için geçerlidir. Yani bu araçların kendisi bir Product olarak temsil edilebilirler. İstemci, sadece kullanmak istediği ürünün farklı bir sunumunu elde etmek isteyecektir. Bu tip bir senaryoda istemcinin asıl ürüne ulaşmak için ele alması gereken üretim aşamalarından uzaklaştırılarak sadece üretmek istediği ürüne ait tipi bildirmesi yeterli olmalıdır. Bu senaryoda araç(Vehicle) aslında üründür(Product). Motorsiklet veya araba ise araç tipleridir ve üretim işlemleri sonucu ortaya bir Vehicle çıkartırlar. Yani desendeki ConcreteBuilder tipleridir. Bu senaryo pekala bir oyun programı içerisindeki araçların üretimi aşamasında göz önüne alınabilir.
Builder Pattern aktörleri aşağıdaki gibidir.
Builder: Product nesnesinin oluşturulması için gereken soyut arayüzü oluşturur. Interface ya da abstract class olabilir. Concrete builderlar için parent niteliğindedir.
ConcreteBuilder: Builder arayüzünü kullanarak implemente edilen concrete builderlar, nesne tiplerini build eden concrete classlardır. Her bir concrete builder bir sunumu build eder.
Product: Concrete builderlar tarafından üretilen clienta sunulan productır.
Director : Kendisine parametre olarak verilen concreteBuilder nesnesi ile Builder arayüzü üzerinden clienta nesne oluşturan classtır.
//Product Class public class House { private String basement; private String structure; private String roof; private String interior; public void setBasement(String basement) { this.basement = basement; } public void setStructure(String structure) { this.structure = structure; } public void setRoof(String roof) { this.roof = roof; } public void setInterior(String interior) { this.interior = interior; } } //Builder class interface HouseBuilder { public void buildBasement(); public void buildStructure(); public void bulidRoof(); public void buildInterior(); public House getHouse(); } //Concrete Builder class class IglooHouseBuilder implements HouseBuilder { private House house; public IglooHouseBuilder() { this.house = new House(); } public void buildBasement() { house.setBasement("Ice Bars"); } public void buildStructure() { house.setStructure("Ice Blocks"); } public void buildInterior() { house.setInterior("Ice Carvings"); } public void bulidRoof() { house.setRoof("Ice Dome"); } public House getHouse() { return this.house; } } //Concrete Builder class class TipiHouseBuilder implements HouseBuilder { private House house; public TipiHouseBuilder() { this.house = new House(); } public void buildBasement() { house.setBasement("Wooden Poles"); } public void buildStructure() { house.setStructure("Wood and Ice"); } public void buildInterior() { house.setInterior("Fire Wood"); } public void bulidRoof() { house.setRoof("Wood, caribou and seal skins"); } public House getHouse() { return this.house; } } //Director class class CivilEngineer { public House getHouse() { return this.houseBuilder.getHouse(); } public void constructHouse(HouseBuilder houseBuilder) { houseBuilder.buildBasement(); houseBuilder.buildStructure(); houseBuilder.bulidRoof(); houseBuilder.buildInterior(); } } class Builder { public static void main(String[] args) { HouseBuilder iglooBuilder = new IglooHouseBuilder(); CivilEngineer engineer = new CivilEngineer(); engineer.constructHouse(iglooBuilder); House house = engineer.getHouse(); System.out.println("Builder constructed: "+ house); } }