JavaScript’te Singleton Tasarım Modeli – JSManifest

JavaScript'te Singleton Tasarım Modeli – JSManifest

Bu yazıda, JavaScript’teki Singleton Design Pattern’i inceleyeceğiz.

Singleton’lar, bir nesnenin yalnızca bir örneğinin gerekli olduğu ancak birçok kez başlatıldığı yazılımda gerekli bir bileşendir.

Örneğin, uygulayacak olsaydık LocalStorage JavaScript’te şöyle görünürdü:

class LocalStorage {
  #data = {}

  constructor(options) {
    this.options = options || {}
  }

  get(key) {
    return this.#data[key]
  }

  set(key, value) {
    this.#data[key] = value
  }

  remove(key) {
    delete this.#data[key]
  }

  clear() {
    this.#data = {}
  }
}

Şimdi, bir fonksiyon bu arayüzü kullanmak istediğinde, burada kod karar verme konusundaki seçimlerimizi düşünelim.

Her yeni bir örneğini başlattığımızda LocalStorage4 yöntem get, set, remove ve clear her durumda var olacaktır. Ancak, yeni örnekler bu yöntemleri orijinal örnekten kopyalamaz. Prototipin bir parçası olarak dahil edildikleri için LocalStorage bunlar paylaşılan yöntemleri, yani her yeni örneği LocalStorage yöntemlerin orijinal örnektekilere referans olmasını sağlayacaktır.

Fabrika işlevleri ve sınıflar arasında karar verirken bunu anlamak çok önemlidir. Muhtemelen fabrikalar hakkında bir veya daha fazla öğreticiyi, sınıflar yerine tavsiye ettikleri yerlerden önce okudunuz. Bazı durumlarda farklı sorunlar yaşanabileceğinden, bunun gibi ipuçlarının herkese uyan tek bir çözüm olmadığını bilmek önemlidir.

Fabrikaları sınıflara tercih etme önerisine katılıyorum fakat Programınız aynı zamanda bir nesnenin örneklerini de sıklıkla oluşturduğunda, sınıfları dikkate almanın zamanı gelmiştir çünkü bunlar, yöntemlerini tüm nesne yaratımlarında paylaşma avantajına sahiptir.

İşte bizim fabrika fonksiyonumuzun eşdeğeri LocalStorage sınıf:

function LocalStorage() {
  let _data = {}
  let _options = {}

  return {
    get(key) {
      return _data[key]
    },
    set(key, value) {
      _data[key] = value
    },
    remove(key) {
      delete _data[key]
    },
    clear() {
      _data = {}
    },
  }
}

Bunu başlatmak şuna benzer:

const localStorage = LocalStorage()

Döndürülen nesne her zaman yeni oluşturulan bir nesne olduğundan bu iyi bir karar değildir. LocalStorage nesneyi üretir.

Bu nedenle, bir program bunlardan yüzlercesini yaratacak olsaydı, bu israf olur çünkü uygulama detayları get, set, remove ve clear asla değişir, bu yüzden onları kopyalamanın ve bellekte yer kaplamanın gerçekten bir anlamı yoktur.

Şu anda Singleton Design Pattern’i kullanmak en iyisidir. LocalStorage Böylece get, set, remove ve clear tüm inşa edilmiş örnekler arasında paylaşılacaktır.

aslında fabrikaları kullanabiliriz bir singleton uygulamak prototip sınıfını kapsülleyecek olsaydık:

function LocalStorage(options) {
  let _data = {}
  let _options = options || {}

  return {
    get(key) {
      return _data[key]
    },
    set(key, value) {
      _data[key] = value
    },
    remove(key) {
      delete _data[key]
    },
    clear() {
      _data = {}
    },
  }
}

const createLocalStorage = (function () {
  return function createLocalStorage(options) {
    if (!ls) {
      ls = LocalStorage(options)
    }
    return ls
  }
})()

ne zaman bizim createLocalStorage fabrika işlevi çağrılırsa, daha önce somutlaştırılmış bir tane olup olmadığını kontrol eder. ls değişken. Varsa, mevcut olanı döndürür. Değilse, yeni bir tane yaratacak ve onu sağ tarafa tokatlayacak. ls değişken:

Diğer uygulamalar

Şimdiye kadar bir Singleton’u korumanın fabrika işlevi yolunu ele aldım. İşte bunu başarmanın diğer yolları:

Sınıf statik yöntemi

Bu uygulama bir sınıf nesnesi kullanır ve iki statik özellikler (teknik olarak bir özellik ve bir yöntem). nasıl eşdeğer olduğuna dikkat edin küresel değişken:

İsim Tanım
_instance Küresel örneğini tutar LocalStorage. Örnekleyiciler tarafından saklanacağı yer burasıdır.
getInstance Bir kontrol gerçekleştirir LocalStorage._instance. Daha önce bir örnek oluşturulduysa, bu döndürülür her zaman. Boşsa, yeni bir örnek oluşturulacak ve üzerine eklenecektir.
class LocalStorage {
  #data = {}

  static _instance = null

  static getInstance(options) {
    if (!LocalStorage._instance) {
      LocalStorage._instance = new LocalStorage(options)
    }

    return LocalStorage._instance
  }

  constructor(options) {
    this.options = options || {}
  }

  get(key) {
    return this.#data[key]
  }

  set(key, value) {
    this.#data[key] = value
  }

  remove(key) {
    delete this.#data[key]
  }

  clear() {
    this.#data = {}
  }
}

Değişken Bildirimi

Singleton oluşturmanın en basit yolu budur. Çalışıyor çünkü içinde ilan edildi küresel kapsam nedeniyle yeniden yazılamaz. const anahtar kelime. Ancak, bunu yapmak için daha verimli yollara sahip olduğunuzda, singleton oluşturmanın en iyi yolu bu değildir:

const MySingleton = {
  sayHello() {
    console.log('hello')
  },
}

Dondur

Bu yaklaşımda biz LocalStorage sınıf. Ancak, bu sefer hiç oluşturmuyoruz. static özellikleri sınıfa aktarır. Biz örneği dondur yerine:

class LocalStorage {
  #data = {}

  static _instance = null

  static getInstance(options) {
    if (!LocalStorage._instance) {
      LocalStorage._instance = new LocalStorage(options)
    }

    return LocalStorage._instance
  }

  constructor(options) {
    this.options = options || {}
  }

  get(key) {
    return this.#data[key]
  }

  set(key, value) {
    this.#data[key] = value
  }

  remove(key) {
    delete this.#data[key]
  }

  clear() {
    this.#data = {}
  }
}

const localStorage = new LocalStorage()

Object.freeze(localStorage)

Bu şekilde sınıfta hiçbir şeyin yazılamamasını sağlıyoruz. Yine de, sürdürmek singleton biraz farklı çalışır.

Kullanarak Object.freeze asla yaratmaya veya somutlaştırmaya çalışmadığımızdan emin olmalıyız. LocalStorage çünkü programımız hata verecektir. Bu, yeniden adlandırmak kadar basit bir anlama gelebilir createLocalStorage ile getLocalStorage ve uygulamanın ömrü boyunca kullanmak.

Singleton uygulamalarında yaygın uygulamalar

  • Singletons ile çalışmak alışılmadık bir durum değildir. asla program sonlandırılana kadar bellekten boşaltın
  • Bir Singleton’ın amacı asla yeniden tanımlanmamak iken, global değişkenler sözcüksel olarak kapsamlandırılır
  • Singleton’lar yöntemlerle değiştirilir

Çözüm

Okuduğunuz için teşekkür ederim ve gelecekte benden daha kaliteli yazılar gelmesini sabırsızlıkla bekliyoruz!

Yazılarıma abone olun 🙂

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.