Builder Pattern Nedir ? Faydaları Nelerdir ?
Yeni bir obje yaratma sürecinde kullanılan tasarım desenidir.
Constructor üzerinden karmaşık şekilde obje yaratma sürecini sadeleştirir.
Karmaşık yapıya sahip objenin oluşturulma sürecinin, bağımsız bir şekilde yapılması gerektiği durumlarda bu pattern kullanılır.
Çok parametreli method çağrımlarının construcor üzerinden halledilmesi Telescoping Constructor problemi olarak geçmektedir. Builder pattern bu probleme bir çözüm olabilir.
Builder Pattern karmaşık sınıfların nesne yaratım sürecini soyutlayan bir pattern’dir.
Builder Pattern ’in Faydaları :
- Tek tip bir üretim süreci
- Soyutlanmış bir yaratım süreci
- Loose coupling
- Thread safety
Bir örnek yapalım :
Bu örneğin ilk aşaması Builder Pattern uygulanmamış hali olacak.
Bir ekran tasarlayalım ve farklı veritabanlarından veriler gelsin bu ekrana.
Aslında sorgular veritabanları için benzer olacak.
Burada önemli olan , ekranı besleyen kısma yeni bir database eklendiğinde koda çok fazla müdahale etmememiz gerekir.
Hazırladığımız sorguların benzer yapım süreçleri olacak ama farklı sonuçları oluşacak. Yaratım sürecini ortaklaştırabiliriz kod tekrarından kaçınmak için.
1)
Proje isimimiz Builder Pattern olsun, builder paketi oluşturalım (Şekil 1).
2)
2 database için 2 farklı sınıf yaratalım.
SqlQuery sınıfı ve MongoDbQuery sınıfı, ikisinde de execute() methodu olacağından bunlar için bir Query interface’i yazalım.
package builder;public interface Query {void execute();}
3)
SqlQuery sınıfı:
package builder;public class SqlQuery implements Query {private String from;private String where;@Overridepublic void execute() {System.out.println(“SqlQuery çalıştırıldı : “ + from + “ where “ + where);}public void setFrom(String from) {this.from = from;}public void setWhere(String where) {this.where = where;}}
MongoDbQuery sınıfı:
package builder;public class MongoDbQuery implements Query {private String from;private String where;@Overridepublic void execute() {System.out.println(“MongoDBQuery çalıştırıldı : “ + from + “ where “ + where);}public void setFrom(String from) {this.from = from;}public void setWhere(String where) {this.where = where;}}
4)
Ana sınıfımız olan Client’ı yazalım:
package builder;public class Client {public static void main(String[] args){String from=”client table “;String where=”client name = ***”;SqlQuery sqlQuery = new SqlQuery();sqlQuery.setFrom(from);sqlQuery.setWhere(where);sqlQuery.execute();MongoDbQuery mongoDbQuery = new MongoDbQuery();mongoDbQuery.setFrom(from);mongoDbQuery.setWhere(where);mongoDbQuery.execute();}}
Client sınıfının çalıştırılması sonucu oluşan çıktı:
Burada aslında Client sınıfında benzer query’ler için gereksiz kod yazdık.
Sorunlar :
Nesnelerimiz (SqlQuery ve MongoDbQuery) birkaç aşamada yaratılabildi.
Bunlar nesnenin yaratım sürecinde tuttarsız bir durum oluşturuyor. Thread safe olmasından emin olmamız için çok daha fazla efor sarf etmemiz gerek.
Kodun iyileştirilmiş hali:
1)
iyileştirilmiş.builder package’i oluşturalım.
2)
Query interface’imiz yine aynı.
public interface Query {void execute();}
3)
QueryBuilder interface’ini yazalım.
Ortak olan methodları topladık.
public interface QueryBuilder {void from(String from);void where(String where);Query getQuery();}
4)
Asıl query’i döndürecek olan QueryBuildDirector sınıfımızı yazalım.
public class QueryBuildDirector {public Query buildQuery(String from, String where, QueryBuilder builder){builder.from(from);builder.where(where);return builder.getQuery();}}
5)
SqlQuery ve MongoDbQuery sınıflarımız aynı bir önceki haliyle.
public class SqlQuery implements Query{private String from;private String where;@Overridepublic void execute() {System.out.println(“SqlQuery çalıştırıldı from: “+from+” where “+where);}public void setFrom(String from) {this.from = from;}public void setWhere(String where) {this.where = where;}}public class MongoDbQuery implements Query{private String from;private String where;@Overridepublic void execute() {System.out.println(“MongoDbQuery çalıştırıldı from: “+from+” where “+where);}public void setFrom(String from) {this.from = from;}public void setWhere(String where) {this.where = where;}}
6)
SqlQuery ve MongoDbQuery için QueryBuilder sınıflarını oluşturalım.
public class SqlQueryBuilder implements QueryBuilder{SqlQuery query = new SqlQuery();@Overridepublic void from(String from) {query.setFrom(from);}@Overridepublic void where(String where) {query.setWhere(where);}@Overridepublic Query getQuery() {return query;}}public class MongoDbQueryBuilder implements QueryBuilder{private MongoDbQuery query = new MongoDbQuery();@Overridepublic void from(String from) {query.setFrom(from);}@Overridepublic void where(String where) {query.setWhere(where);}@Overridepublic Query getQuery() {return query;}}
7)
Client sınıfını yazalım :
public class Client {public static void main(String[] args){//Director’ı kuruyoruzQueryBuildDirector director = new QueryBuildDirector();String from=”client table”;String where=”client name = …”;//kullanacağımız sql query’i hazırlıyoruz
// Hazırladığımız sorgu tek seferde oluşturulmuş ve çalıştırılmış olduQueryBuilder builder = new SqlQueryBuilder();Query query = director.buildQuery(from, where, builder);query.execute();//kullanacağımız mongoDb query’i hazırlıyoruzbuilder = new MongoDbQueryBuilder();query = director.buildQuery(from, where, builder);query.execute();}}
Yeni client sınıfının çıktısı :
Yazımın sonuna geldik, okuyanlar için umarım faydalı olmuştur :)
Sevgiler