İşte Kompozit Tasarım Modelini Bilmeniz İçin 6 Neden – JSManifest

İşte Kompozit Tasarım Modelini Bilmeniz İçin 6 Neden – JSManifest

Bileşik desen, dinamik kullanıcı arayüzleri geliştirirken İsviçre çakısı olabilir. Web uygulamaları geliştirirken istemci tarafında DOM ile çalışırız. Bu, DOM’nin nasıl yapılandırıldığı nedeniyle mükemmeldir.

Amaç, bir nesneyi temsil eden belirli bir ağaç yapısında birden fazla nesneyi bir araya getirmektir. parça-bütün hiyerarşisi.

A parça-bütün ilişki, bir koleksiyondaki her nesnenin bir Bölüm arasında tüm kompozisyon. Bu “tüm” kompozisyon bir koleksiyondur parçalar. Parçalı bir hiyerarşiyi düşündüğümüzde, bu, her bireyin “yaprak” veya “düğüm” ağaçtaki diğer tüm yaprak veya düğümlerle aynı şekilde işlenir ve programımızda tek tip olarak çalışılmasına izin verir. Bu, bir nesne koleksiyonunun veya grubunun (yaprakların/düğümlerin alt ağacı) olduğu anlamına gelir. ayrıca bir yaprak veya düğüm.

Görsel bir perspektiften baktığımızda nasıl göründüğü:

Yazılım mühendisliğinde geliştiriciler, derinlemesine iç içe nesnelerle çalışmaları gereken ve daha sonra uygulama ayrıntıları hakkında fazla endişelenmeleri gerekmeyen kalıptan yararlanabilir. Bu, bu yazıda göreceğimiz gibi, karmaşık sorunları çözmeye yardımcı olabilecek güçlü bir tekniktir.

Bu yazımda Kompozit Tasarım Modelinin Sizin Tarafınızdan Öğrenilmesi Gereken En Az 5 Sebepten bahsedeceğim.

Tek nesnelerle yaptığınız gibi koleksiyonlarla da çalışabilirsiniz.

Nesnelerle ve nesne koleksiyonlarıyla tekdüzelik içinde çalışmak zaten güçlüdür.

Büyük olasılıkla zaten onu kullanan kodla çalıştınız. DOM’a aşinaysanız, DOM düğümlerinden alt geçişlere zaten aşinasınızdır.

const container = document.getElementById('root')

function traverse(callback, elem) {
  if (elem.children.length) {
    for (const childNode of elem.children) {
      callback(childNode)
      traverse(callback, childNode)
    }
  }
}

DOM, düğümlerin kendisini çevreleyen düğümlerle bir parça-bütün ilişkisine sahip olduğu bir şekilde yapılandırıldığından, DOM ile tek tip olarak çalışabiliriz. Aşağıdaki bu örnek, bir öğenin özelliklerini vurgulamanın basit bir yoludur. img basit bir travers işlevi kullanan çocuklar:

#gallery-container {
  margin: auto;
}

#gallery {
  display: flex;
  max-height: 200px;
  justify-content: center;
}

#gallery img {
  max-width: 100px;
}

.highlight {
  border: 1px solid magenta;
}

button {
  display: block;
  margin: auto;
}
<div id="root">
  <main id="content">
    <div id="gallery-container">
      <div id="gallery">
        <img src="https://jsmanifest.s3.us-west-1.amazonaws.com/other/apple.jpg"></img>
        <img src="https://jsmanifest.s3.us-west-1.amazonaws.com/other/orange.jpg"></img>
        <img src="https://jsmanifest.s3.us-west-1.amazonaws.com/other/banana.jpg"></img>
      </div>
    </div>
		<div style="height: 10px"></div>
		<button type="button" onclick="function() { highlight(); }">
			Highlight
		</button>
 	</main>
</div>
const container = document.getElementById('root')

function traverse(callback, elem) {
  if (elem && elem.children && elem.children.length) {
    for (const childNode of elem.children) {
      callback(childNode)
      traverse(callback, childNode)
    }
  }
}

document.querySelector('button').addEventListener('click', function () {
  traverse(function onChild(childNode) {
    console.log(childNode.tagName)
    if (childNode.tagName === 'IMG') {
      childNode.classList.add('highlight')
    }
  }, document.getElementById('gallery'))
})

kenarlıklı-dom-düğümlerini vurgula

Özyineleme daha kolay hale gelir

Önceki kod örneğinde, DOM’yi geçmenin bir DOM düğümleri koleksiyonunu vurgulamamıza nasıl izin verdiğini gördük. Ama kodun da gösterdiği şey özyineleme içinde traverse işlev. Özyineleme çocuk oyuncağı haline gelir çünkü kod çok daha küçük hale gelir ve bu da kodun daha kolay korunmasına ve okunmasına yardımcı olur. gerçekleştirmeye gerek yoktur. for loop veya tüm torunları geçmek ve bunlara erişmek için herhangi bir durumu takip edin.

Herhangi bir DOM öğesinin konumunu bulabilirsiniz

Bileşik yapının doğası gereği, bir DOM düğümünün ağacında dolaşmak için bu yetenekten yararlanabiliriz.

DOM’da bir öğenin konumunu bulmak, özellikle farklı öğelerle ince ayar yapıldığında bir kabus olabilir. position değerler.

Tabii ki sadece şöyle bir şey kullanabiliriz myElement.getBoundingClientRect() ve bize pozisyon döndürdüğü için bir gün olarak adlandırın. Ancak bu gerçekten güvenilir değil çünkü sayfayı aşağı kaydırırsanız aslında negatif bir değer elde edebilirsiniz (bu durumda window.pageYOffset) çünkü kaydırılan pencereye göre hesaplanır.

Bir elemanın DOM’daki konumunu çapraz geçiş yaparak bulmak için kalıptan yararlanabiliriz. yukarı ağaç çünkü tüm bu arayüz:

function getParentOffset(el): number {
  if (el.offsetParent) {
    return el.offsetParent.offsetTop + getParentOffset(el.offsetParent)
  } else {
    return 0
  }
}

Tepkide matkabı nasıl destekleyeceğinizi anlayabilirsiniz

Bunu söylemek aptalca gelebilir, ancak pervane delmenin, aşağıdakileri paylaşan her bir tepki bileşenine bağlı olduğunu anlamalısınız. children arabirim (döndürülen öğe/bileşenler children kamera ARKASI):

import React, { useState } from 'react'

function Parent() {
  const [myLabel, setMyLabel] = React.useState('')

  React.useEffect(() => {
    setMyLabel('Hello')
  }, [])

  return <ChildA label={myLabel} />
}

function ChildA({ label }) {
  return <ChildB label={label} />
}

function ChildB({ label }) {
  return (
    <>
      Our label is: <ChildC label={label} />
    </>
  )
}

function ChildC({ label }) {
  return <span>{label}</span>
}

export default Parent

Genişletilebilirlik ve Ölçeklenebilirlik

Yaprak düğümlerimizin/bileşiklerimizin imzasını veya arabirimini tuttuğumuz sürece, mevcut nesneleri genişletmemiz gerektiğinde nesnelerimizin tekdüzeliğini sürdürmek çok basit bir iştir. Bu, ölçeklenebilirliğin gelecekte çok fazla sorun olmayacağı anlamına geliyor.

Formlar kolaylıkla oluşturulabilir

Formlar, sağlam uygulamalar oluşturmadaki etkinliğini gösteren harika gösterilerdir. Formları geliştirirken bu kalıbın sağladığı gücü gösteren bir örnek:

class Form {
  constructor(...fields) {
    this.el = document.createElement('form')
    this.fields = fields.reduce((acc, field) => {
      acc[field.getName()] = field
      this.el.appendChild(field.el)
      return acc
    }, {})
  }

  get value() {
    const values = {}

    for (const [name, field] of Object.entries(this.fields)) {
      values[name] = field.value
    }

    return values
  }

  getName() {
    return this.el.name
  }

  setName(name) {
    this.el.name = name
  }

  render() {
    if (!document.body.contains(this.el)) {
      document.body.appendChild(this.el)
    }
  }

  submit() {
    
  }
}

class Field {
  constructor(name = '', value = '') {
    this.name = name
    this.value = value
  }

  getName() {
    return this.name
  }

  setName(name) {
    this.name = name
  }
}

class InputField extends Field {
  constructor(...args) {
    super(...args)
    this.el = document.createElement('input')
  }

  get value() {
    if (!this.el) return ''
    return this.el.value
  }

  set value(value) {
    if (this.el) {
      this.el.value = value
    }
  }
}

class SelectField extends Field {
  constructor(...args) {
    super(...args)
    this.el = document.createElement('select')
    this.selected = ''
  }

  get value() {
    return this.el.value
  }

  set value(value) {
    if (this.el) {
      this.el.value = value
    }
  }

  select(option) {
    this.el.value = option
  }

  setOptions(options) {
    this.options = options
  }
}

class EmployeeField extends Field {
  constructor(...args) {
    super(...args)
    this.el = document.createElement('div')
    this.firstNameField = new InputField('firstName')
    this.lastNameField = new InputField('lastName')
    this.el.appendChild(this.firstNameField.el)
    this.el.appendChild(this.lastNameField.el)
  }

  get value() {
    return {
      [this.firstNameField.getName()]: this.firstNameField.value,
      [this.lastNameField.getName()]: this.lastNameField.value,
    }
  }

  set value(values) {
    for (const [key, value] of Object.entries(values)) {
      if (key === 'firstName') {
        this.firstNameField.value = value
      } else if (key === 'lastName') {
        this.lastNameField.value = value
      }
    }
  }

  setFirstName(firstName) {
    this.firstNameField.value = firstName
  }

  setLastName(lastName) {
    this.lastNameField.value = lastName
  }
}

Genişletme Field sınıf basit ve kısaydı. Örneklerimizin bileşik doğası sayesinde, üniformayı çağırarak tüm değerleri Nice JSON nesnesine çekebiliyoruz. value alıcı işlevi:

const emailField = new InputField('email')
const nameField = new InputField('name')
const genderSelectField = new SelectField('gender')
const employeeField = new EmployeeField('employee')
const form = new Form(emailField, nameField, genderSelectField, employeeField)

emailField.value = 'pfft@gmail.com'
nameField.value = 'loc'
genderSelectField.value = 'Female'
employeeField.setFirstName('Holly')
employeeField.setLastName('Le')

console.log(form.value)

Sonuç:

{
  "email": "pfft@gmail.com",
  "name": "loc",
  "gender": "",
  "employee": { "firstName": "Holly", "lastName": "Le" }
}

Geliştirici, bileşenleri kullanırken herhangi bir uygulama ayrıntısı hakkında endişelenmek zorunda değildir ve bu, uygulamaları için gerçek kodu yazmaya odaklanmalarını sağlar.

Çözüm

Ve bu yazının sonu burada bitiyor! Umarım bunu faydalı bulmuşsunuzdur ve gelecekte daha fazlasını bekleyin!

Bir cevap yazın

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