Merhaba,

 

Bu yazıda Node.js ile Builder Design Pattern kullanımından bahsedeceğim.

 

Builder Design Pattern ile hem class (sınıf) oluştururken kullandığımız constructor (kurucu metod) içerisindeki parametreleri esnek bir hale getirebilir hem de okunaklı ve temiz bir kod yapısı elde edebiliriz. Örneğin şu şekilde host, port ve path parametreleri alıp URL oluşturan bir URL Builder sınıfımız olsun:

 

UrlBuilder.js:

class UrlBuilder {
  
  constructor(host, port, path) {
    this.host = host
    this.port = port
    this.path = path
  }

  build() {
    let url = 'https://'
    url += this.host || ''
    url += this.port ? ':' + this.port : ''
    url += this.path || ''

    console.log(url)
  }

}

module.exports = UrlBuilder

 

Bir de bu sınıfı kullanacağımız şu şekilde bir app.js dosyamız olsun:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder('yusufborucu.com', 8000, '/test').build()

 

Kodu çalıştırıp çıktımıza bakalım:

node app

 

Konsol çıktısı:

https://yusufborucu.com:8000/test

 

Peki oluşturacağımız URL'de port olmayacaksa ne yapacaktık? app.js üzerinde bu sınıfı şu şekilde kullanacaktık:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder('yusufborucu.com', undefined, '/test').build()

Konsol çıktısı:

https://yusufborucu.com/test

 

Burada constructor'ın alacağı parametrelere oldukça bağımlı bir durumdayız, ayrıca ortada çirkin bir kod var. 

 

Şimdi bir de URL'in https ile başlayıp başlamayacağını ve query parametreleri alıp almayacağını belirten parametrelerimiz olduğunu da hesaba katalım. Bu durumda UrlBuilder üzerinde şu değişiklikleri yapacaktık:

 

UrlBuilder.js:

 class UrlBuilder {
  
  constructor(https, host, port, path, queryParams) {
    this.https = https
    this.host = host
    this.port = port
    this.path = path
    this.queryParams = queryParams
  }

  build() {
    let url = this.https ? 'https://' : 'http://'
    url += this.host || ''
    url += this.port ? ':' + this.port : ''
    url += this.path || ''
    if (this.queryParams) {
      let params = this.queryParams
      Object.keys(params).forEach((key, item) => {
        let prefix = item == 0 ? '?' : '&'        
        url += prefix + key + '=' + params[key]
      })
    }

    console.log(url)
  }

}

module.exports = UrlBuilder

 

app.js üzerinde de şu şekilde kullanacaktık:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder(true, 'yusufborucu.com', 8080, '/test', { key1: "value1", key2: "value2" }).build()

Konsol çıktısı:

https://yusufborucu.com:8080/test?key1=value1&key2=value2

 

Diyelim ki port ve query parametreleri olmayacak. Bu durumda da app.js üzerinde şu şekilde kullanacaktık:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder(true, 'yusufborucu.com', undefined, '/test', undefined).build()

Konsol çıktısı:

https://yusufborucu.com/test

 

Şimdi de Builder Design Pattern ile bu duruma nasıl bir çözüm getirebileceğimize bakalım. UrlBuilder sınıfımızı şu şekilde oluşturalım:

 

UrlBuilder.js:

class UrlBuilder {

  constructor() {
    this.isHttps = undefined
    this.hostName = undefined
    this.portNumber = undefined
    this.pathString = undefined
    this.queryParamsObject = undefined
  }

  https() {
    this.isHttps = true
    return this
  }

  host(data) {
    this.hostName = data
    return this
  }

  port(data) {
    this.portNumber = data
    return this
  }

  path(data) {
    this.pathString = data
    return this
  }

  queryParams(data) {
    this.queryParamsObject = data
    return this
  }

  build() {
    let url = this.isHttps ? 'https://' : 'http://'
    url += this.hostName
    url += this.portNumber ? ':' + this.portNumber : ''
    url += this.pathString ? this.pathString : ''
    if (this.queryParamsObject) {
      let params = this.queryParamsObject
      Object.keys(params).forEach((key, item) => {
        let prefix = item == 0 ? '?' : '&'        
        url += prefix + key + '=' + params[key]
      })
    }
    console.log(url)
  }
}

module.exports = UrlBuilder

 

app.js üzerinde de şu şekilde kullanalım:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder()
    .port(8080)
    .host("yusufborucu.com")
    .path("/test/hello/world")
    .queryParams({ key1: "value1", key2: "value2" })
    .https()
    .build()

Konsol çıktısı:

https://yusufborucu.com:8080/test/hello/world?key1=value1&key2=value2

 

Örneğin port ve https olmama durumunda da şöyle kullanacaktık:

 

app.js:

const UrlBuilder = require('./UrlBuilder')

new UrlBuilder()
    .host("yusufborucu.com")
    .path("/test/hello/world")
    .queryParams({ key1: "value1" })
    .build()

Konsol çıktısı:

http://yusufborucu.com/test/hello/world?key1=value1

 

Görüldüğü üzere Builder Design Pattern'ı kullanarak hem constructor'ı esnek bir hale getirdik, hem de temiz ve okunaklı bir kod yapısı elde ettik.

 

Umarım yararlı olmuştur.

 

İyi çalışmalar.