
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ü” ş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. Room
ve bir oda en az iki tane olana kadar başlamaz. Participant
s. Ancak Participant
yerel ses/videolarını başlatana kadar akışa başlayamazlar MediaTrack
s. 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ı.
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 LivingThing
Yalnı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:
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!