JavaScript’te Köprü Tasarım Modeli – JSManifest

JavaScript'te Köprü Tasarım Modeli – JSManifest

Bu yazıda JavaScript’te Bridge Design Pattern’i inceleyeceğiz. Bu, softare uygulamalarında önemli bir etki yaratan en çok kullanılan kalıplardan biridir. Uygulanmasında endişelerin ayrılmasını kolayca destekleyen bir kalıptır ve ölçeklenebilir.

İşte bu kalıbı gösteren diyagram:

Genellikle iki ana katılımcılar (veya varlıkhangisini adlandırmak istersen) Köprü Kalıbına dahil olanlar.

İlk ve en üst kısım soyut katmandır. Bu basitçe bir sınıf olarak uygulanabilir:

class Person {
  constructor(name) {
    this.name = name
  }

  talk(message) {
    console.log(message)
  }
}

Köprü Modelinde, soyut katman, temel arayüz yöntemlerini ve/veya özelliklerini bildirir. Ancak uygulama detaylarını umursamıyorlar çünkü bu onların işi değil. Bu kalıbın avantajlarından yararlanabilmek için, kodumuzun daha sonra sıkı bir şekilde bağlanmaması ve yönetilebilir kalması için bu şekilde tutulmalıdır.

Bunun yerine soyut katman köprüler açar bu daha sonra modelin ikinci ana kısmına yol açar: uygulama katmanlar (genellikle sınıflar uygulamada) bu köprülere bağlıdır ve müşteri (veya sen) çekimleri arayın. “Ekli” kelimesi, kod terimini anlamak için insan tarafından okunabilen bir terim biçimimdir. Referanslar veya işaretçiler:

köprü-desen-gerçek-hayat-vs-kod-diagram1.png

“Köprü” şu şekilde kodda görünür şekilde görünebilir:

class Theme {
  constructor(colorScheme) {
    this.colorScheme = colorScheme 
  }

  getColorScheme() {
    return this.colorScheme 
  }
}

gibi web sitelerini ziyaret ettiyseniz https://dev.to veya https://medium.com profilinizin içinden erişebileceğiniz bir tema özelliğine sahipler. genellikle bir geçiş tema düğmesi. Tema soyut katmandır. Açık ve koyu arasında geçiş yapmanın gerçek uygulaması büyük olasılıkla bulunur dışarıda uygulama katmanındaki/katmanlarındaki soyut katman konumunun.

Köprü Kalıbı nerede ve ne zaman kullanılmalıdır?

Gerçek dünyadaki bazı uygulamalar, “köprü etkisinin” “canlı” olacağı şekilde kodlanmıştır. Çalışma süresi. İki nesne arasında bu tür bir bağlantıya/bağlamaya ihtiyaç duyduğunuzda, bu, Bridge Modelini kendi avantajınıza kullanabileceğiniz zamandır.

Buna iyi bir örnek Twilio-video, web uygulamalarınıza (Zoom gibi) gerçek zamanlı ses ve video eklemenizi sağlayan bir JavaScript kitaplığı. Bu kütüphanede, Oda her zaman boş bir oda olarak başlatılır. Sınıf bir işaretçiyi tutar. LocalParticipant(bir görüntülü sohbet odasına katıldığınızda sen bunlar LocalParticipant ekranınızda) ancak LocalParticipant aslında çalışmıyor veya somutlaştırılmıyor henüz bağlanana ve yalnızca çalışan kodda mümkün olan odaya abone olana kadar.

Kodlarını tararsanız, birçok alanda köprüler görürsünüz. olmadan bir görüntülü sohbet oturumu oluşturulamaz. Roomve bir oda en az iki tane olana kadar başlamaz. Participants. Ancak Participant yerel ses/videolarını başlatana kadar akışa başlayamazlar MediaTracks. Bu sınıflar yukarıdan aşağıya bir hiyerarşi içinde birlikte çalışır. Birbirine bağlı birden fazla sınıfa sahip olmaya başladığınızda, bu aynı zamanda Köprü Modelini düşünmek için de iyi bir zamandır.

Köprü Modelinin yararlı olduğu başka bir senaryo, bir nesnenin uygulamasını birden çok nesneyle paylaşmak istediğiniz zamandır.

Örneğin, MediaStreamTrack class, bir akış için bir medya izini temsil eder. Ondan “köprü” oluşturan en yaygın iki uygulama ses ve video parçaları.

köprü-tasarım-pattern-media-stream-track.png

Ek olarak, uygulama detayları genellikle türetilmiş sınıflar içinde gizlenir.

uygulama

Bir problem ve onun masaya getirdiği çözüm hakkında iyi bir fikir edinmek için kendi Köprü Modeli varyasyonumuzu uygulayalım.

jenerik ile başlayalım Thing herhangi birini temsil edebilen sınıf şey:

class Thing {
  constructor(name, thing) {
    this.name = name
    this.thing = thing
  }
}

Genişleyen yüksek seviyeli bir soyutlama sınıfı oluşturabiliriz. Thing. Bunu arayabiliriz LivingThing ve adında bir yöntem tanımlayacaktır eat. Gerçek dünyadaki tüm canlılar, hayatta kalmak için yemek yeme yeteneği ile doğarlar. Bunu kodumuzda taklit edebiliriz. Bu, üst düzey soyut katmanda kalacaktır:

class LivingThing extends Thing {
  constructor(name, bodyParts) {
    super(name, this)
    this.name = name
    
    this.mouth = bodyParts?.mouth || null
  }

  eat(food) {
    this.mouth.open()
    this.mouth.chew(food)
    this.mouth.swallow()
    return this
  }
}

bir köprü açtığımızı görüyoruz. Mouth sınıf. Şimdi o sınıfı tanımlayalım:

class Mouth extends Thing {
  constructor() {
    super('mouth', this)
  }

  chew() {}
  open() {}
  swallow() {}
}

Şimdi göz önünde bulundurulması gereken şey (hiçbir kelime oyunu değil), bizim Mouth ağız ve yemek arasındaki iletişimin mantığını yazdığımız bir uygulama katmanı olacak.

Bu uygulama tamamen Mouth. bu LivingThing bu uygulama ayrıntılarını umursamıyor ve bunun yerine bu rolü tamamen bizim durumumuzda olan uygulama sınıflarına devrediyor. Mouth.

Biraz duralım ve bu kısım hakkında konuşalım. Eğer LivingThing herhangi bir uygulamasında yer almıyor bu aslında bizim için yararlı bir kavram. eğer başka yapabilirsek LivingThingYalnızca uygulamaların türetilmesi için arabirim sağlaması gereken s, o zaman diğer senaryolar için daha geniş bir sınıf yelpazesi yapabiliriz.

Bir MMORPG oyununda şunları kullanabiliriz: LivingThing ve hepsinden daha fazlasını yapın miras a Işaretçi bir mouth otomatik olarak:

class Character extends LivingThing {
  constructor(name, thing) {
    super(name, this)
    this.thing = thing
    this.hp = 100
    this.chewing = null
  }

  attack(target) {
    target.hp -= 5
    return this
  }

  chew(food) {
    this.chewing = food
    return this
  }

  eat(food) {
    this.hp += this.chewing.hpCount
    return this
  }
}

class Swordsman extends Character {}
class Rogue extends Character {}
class Archer extends Character {}
class Sorceress extends Character {}

class Potion {
  constructor(potion) {
    this.potion = potion
  }

  consume(target) {
    if (this.potion) {
      this.eat(this.potion)
      this.potion = null
    }
  }
}

class Food {...}

const sally = new Sorceress()
const mike = new Rogue()

mike.attack(sally)
sally.eat(new Food(...))

Köprü modelinin, geliştiricilerin platformlar arası uygulamalar oluşturmasını sağladığı iyi bilinmektedir. Bu yeteneği zaten örneklerimizde görebiliyoruz. Aynı MMORPG oyununu yeniden kullanarak yapabiliriz. LivingThing yeni bir kod bazında. Yalnızca aşağıdaki gibi uygulama katmanlarını yeniden uygulamamız gerekiyor Mouth farklı platformlara bağlantılar oluşturmak için.

Oyunlarla sınırlı değiliz. bizim beri LivingThing geneldir ve herhangi bir şey için anlamlıdır hareket eder bir robot gibi tamamen farklı bir şey yaratmak için kullanabiliriz. IoT cihaz programı ve yeme davranışını simüle edin LivingThing.

Sahte MMORPG oyunumuza geri dönersek, daha fazla köprü oluşturmak için köprüler kullanılabilir. MMORPG’de genellikle kullanıcıların ayarlarını düzenleyebilecekleri bir profil sayfası bulunur.

Bu Profile bir profil api’si gibi çalışmasını sağlamak için bir parça takımını tanımlamak için Köprü Tasarım Modelini kullanabilir:

let key = 0

class Profile {
  constructor({ avatar, character, gender, username }) {
    this.character = null 
    this.gender = null
    this.username = username
    this.id = ++key
  }

  setCharacter(value) {
    this.character = value
    return this
  }

  setGender(value) {
    this.gender = value
    if (value === 'female') {
      this.showRecommendedEquipments('female')
    } else {
      this.showRecommendedEquipments('male')
    }
    return this
  }

  setUsername(value) {
    this.username = value
    return this
  }

  showRecommendedEquipments() {
    
  }

  save() {
    return fetch(`https://some-database-endpoint.com/v1/profile/${key}`, {
      method: 'POST',
      body: JSON.stringify({
        character: this.character,
        gender: this.gender,
        username: this.username,
      }),
    })
  }
}

Diğer makalelerimden bazılarını okuduysanız, bu Bağdaştırıcı veya Strateji modeline benzer gelebilir.

Bununla birlikte, farklı sorunları çözen belirgin farklılıklar vardır:

Bağdaştırıcı modelinde çözdüğü sorun koddan (veya önceki çalışma zamanına) burada ilk önce Adaptörü oluşturacağız, ardından hemen geri kalanıyla başlayacağız:

aksios-sahte-adaptör

function adapter() {
  return function (config) {
    var mockAdapter = this
    
    
    if (arguments.length === 3) {
      handleRequest(mockAdapter, arguments[0], arguments[1], arguments[2])
    } else {
      return new Promise(function (resolve, reject) {
        handleRequest(mockAdapter, resolve, reject, config)
      })
    }
  }.bind(this)
}

Bunu önceki snippet’lerimizle karşılaştırın Twilio-video ve farkı hemen hissedeceksiniz.

Çözüm

Ve bu yazının sonu burada bitiyor! Umarım bunu değerli bulmuşsunuzdur ve gelecekte daha fazlasını ararsınız!

Bir cevap yazın

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