Compositor JavaScript

A tradução do artigo foi preparada em antecipação ao início do curso “Desenvolvedor JavaScript. Básico " .








Neste artigo, analisaremos um dos padrões de design estrutural em JavaScript - o vinculador . Na engenharia de software, o vinculador permite que você se refira a grupos de objetos como se fossem objetos separados, o que garante que a estrutura geral desses objetos e suas combinações sejam consistentes.



A principal tarefa de um vinculador é combinar muitos objetos em uma única estrutura de árvore . Esta estrutura em árvore representa uma hierarquia do particular ao todo .



Para entender melhor como o vinculador funciona, você precisa entender como a hierarquia de particular a todo funciona e como pode ser visualizada.



Na hierarquia do particular ao todo, cada objeto da coleção faz parte da composição geral . Essa composição geral, por sua vez, é uma coleção de suas partes . A hierarquia do particular para o todo é construído como uma árvore-como estrutura, onde cada indivíduo "folha" ou "nó" é percebido e processado apenas como qualquer outra folha ou nó em qualquer parte da árvore. Portanto, um grupo ou coleção de objetos (uma subárvore de folhas / nós) também é uma folha ou um nó.



Visualmente, ele pode ser representado da seguinte forma:







Agora que temos uma compreensão mais clara da relação entre o privado e o todo, vamos voltar ao termo vinculador... Determinamos que o uso do linker se destina a combinar os objetos mencionados (folhas / nós) em uma árvore de acordo com este princípio.



Assim, obtemos um padrão de design no qual cada elemento de uma coleção também pode incluir outras coleções , o que permite que estruturas profundamente aninhadas sejam construídas.



Estrutura interna



Cada nó na árvore compartilha um conjunto comum de propriedades e métodos que permitem manter e interagir com objetos individuais da mesma forma que com coleções de objetos. Essa interface pressupõe a construção de algoritmos recursivos que iteram sobre todos os objetos da coleção de composição.



Onde esse padrão se aplica?



Em sistemas operacionais, esse padrão permite muitas possibilidades, como a criação de diretórios dentro de diretórios.



Arquivos (por conveniência, todos os objetos em um diretório podem ser considerados “elementos” ) são folhas / nós (partes) dentro de um composto (diretório) inteiro. Um subdiretório criado em um diretório é, da mesma forma, uma folha ou um nó que inclui outros elementos, como vídeos, imagens, etc. Ao mesmo tempo, diretórios e subdiretórios também são compostos , pois são coleções de partes separadas (objetos, arquivos, etc. etc.).



Bibliotecas populares como React ou Vue usam esse padrão extensivamente para construir interfaces confiáveis ​​e reutilizáveis. Todos os elementos das páginas da web que você vê são representados como componentes . Cada componente de uma página da web é uma folha de uma árvore e pode combinar muitos componentes (neste caso, um composto é formado , mas ainda é uma folha de uma árvore ). É uma ferramenta poderosa que simplifica muito o desenvolvimento para usuários de bibliotecas. Além disso, permite criar aplicativos escaláveis ​​que envolvem vários objetos.



Por que este modelo é interessante?



Resumindo: é muito poderoso.



O vinculador é um padrão de design poderoso porque permite que um objeto seja tratado como um composto usando uma interface comum para todos os objetos.



Isso significa que você pode reutilizar objetos sem medo de incompatibilidade potencial com outros.



Ao desenvolver um aplicativo, você pode precisar trabalhar com objetos que possuem uma estrutura em árvore, caso em que usar esse padrão pode ser muito eficaz.



Exemplos de



Digamos que estejamos desenvolvendo um aplicativo para uma empresa que ajuda os médicos a se certificarem de plataformas que prestam serviços de saúde remotamente. O processo inclui a coleta de assinaturas para documentos legais.



Vamos trabalhar com uma classe Documentque terá uma propriedade signaturecom valor padrão false. Se o médico assinar o documento, o valor da assinatura será alterado para sua assinatura. Também definimos um método nesta classe signpara implementar esta função.



É assim que vai ficar Document:



class Document {
  constructor(title) {
    this.title = title
    this.signature = null
  }
  sign(signature) {
    this.signature = signature
  }
}




Agora, usando o vinculador, forneceremos suporte para métodos semelhantes aos definidos em Document.



class DocumentComposite {
  constructor(title) {
    this.items = []
    if (title) {
      this.items.push(new Document(title))
    }
  }

  add(item) {
    this.items.push(item)
  }

  sign(signature) {
    this.items.forEach((doc) => {
      doc.sign(signature)
    })
  }
}


Agora a graça do modelo se torna aparente. Preste atenção aos dois últimos trechos de código: Vamos dar uma olhada no modelo visualmente:



Ótimo! Parece que estamos no caminho certo. O que obtivemos corresponde ao esquema apresentado acima.







Portanto, nossa estrutura de árvore contém duas folhas / nós - Documente DocumentComposite. Ambos compartilham a mesma interface e, portanto, atuam como “partes” de uma única árvore composta .



Deve-se notar aqui que um nó folha / árvore que não é um composto ( Document) não é uma coleção ou grupo de objetos e, portanto, não continuará ramificando. No entanto, a folha / nó sendocomposto, contém uma coleção de peças (no nosso caso é items). Lembre-se também de que Documentambos DocumentCompositecompartilham uma interface comum e, portanto, compartilham o método de sinalização.



Então, qual é a eficácia dessa abordagem? Embora DocumentComposite use uma única interface porque usa um método de assinatura como o Document, ele adota uma abordagem mais eficiente enquanto atinge seu objetivo final.



Então, em vez de uma estrutura como esta:



const pr2Form = new Document(
  'Primary Treating Physicians Progress Report (PR2)',
)
const w2Form = new Document('   (W2)')

const forms = []
forms.push(pr2Form)
forms.push(w2Form)

forms.forEach((form) => {
  form.sign('Bobby Lopez')
})


Podemos modificar o código e torná-lo mais eficiente aproveitando as vantagens do vinculador:



const forms = new DocumentComposite()
const pr2Form = new Document(
  '     (PR2)',
)
const w2Form = new Document('   (W2)')
forms.add(pr2Form)
forms.add(w2Form)

forms.sign(' ')

console.log(forms)


Com esta abordagem, só precisamos executar a assinatura uma vez após adicionar todos os documentos necessários, e esta função assinará todos os documentos.



Você pode verificar isso observando a saída da função console.log(forms):







No exemplo anterior, tivemos que adicionar documentos manualmente a uma matriz e, em seguida, iterar independentemente sobre cada documento e executar a função signpara assiná-lo.



Além disso, não se esqueça de que o nosso DocumentCompositepode incluir uma coleção de documentos.



Então, quando fizemos isso:



forms.add(pr2Form) // 
forms.add(w2Form) // 


Nosso esquema assumiu a seguinte forma:







Adicionamos duas formas, e agora este esquema é quase completamente idêntico ao original:





Mesmo assim, nossa árvore para de crescer, pois sua última folha formou apenas duas folhas, o que não corresponde exatamente ao diagrama da última imagem. Se, em vez disso, fizemos o w2form um composto, como mostrado aqui:



const forms = new DocumentComposite()
const pr2Form = new Document(
  '     (PR2)',
)
const w2Form = new DocumentComposite('   (W2)')
forms.add(pr2Form)
forms.add(w2Form)

forms.sign(' ')

console.log(forms)


Então nossa árvore pode continuar a crescer:





Em última análise, teríamos alcançado o mesmo objetivo - todos os documentos teriam sido assinados:





É aqui que o vinculador entra.



Conclusão



É tudo por agora! Espero que esta informação tenha sido útil para você. Além disso!



Me encontre no meio







Consulte Mais informação:






All Articles